一个简单的Java代码,运行良好但function有点难以理解

以下简单的Java程序似乎通过语句System.out.println("Hello World");显示字符串Hello World System.out.println("Hello World"); 但事实并非如此。 它只是用另一个字符串替换它,在这种情况下, 美好的一天! 并在控制台上显示它。 字符串Hello World根本不显示。 让我们看看Java中的以下简单代码片段。

 package goodday; import java.lang.reflect.Field; final public class Main { public static void main(String[] args) { System.out.println("Hello World"); } static { try { Field value = String.class.getDeclaredField("value"); value.setAccessible(true); value.set("Hello World", value.get("Good Day !!")); } catch (Exception e) { throw new AssertionError(e); } } } 

这里只有一个关于此代码的问题。 它完全按预期工作,但我不能减少字符串的好日子! 。 如果尝试这样做,则会导致java.lang.ArrayIndexOutOfBoudsException 。 如果长度增加,程序运行良好但显示字符串中的其余字符被截断意味着两个字符串的长度应该有些相同。 为什么? 这是我无法理解的事情。

value字段是char[] ,它在内部存储字符串用作其后备存储的字符数组。 其他字段表示字符数组的初始偏移量以及字符串的长度。 (因此,为了获取子字符串,它只是创建一个新的String对象,该对象引用相同的char[]但具有不同的起始偏移量和长度。)

如果你也修改这些字段,你可以用字符串做任何你喜欢的事情。 样品:

 import java.lang.reflect.Field; public class Test { // Obviously in real code you wouldn't use Exception like this... // Although hacking string values with reflection is worse, of course. public static void main(String[] args) throws Exception { System.out.println("Hello World"); replaceHelloWorld("Goodbye!"); System.out.println("Hello World"); replaceHelloWorld("Hello again!"); System.out.println("Hello World"); } static void replaceHelloWorld(String text) throws Exception { // Note: would probably want to do hash as well... copyField(text, "Hello World", "value"); copyField(text, "Hello World", "offset"); copyField(text, "Hello World", "count"); } static void copyField(String source, String target, String name) throws Exception { Field field = String.class.getDeclaredField(name); field.setAccessible(true); field.set(target, field.get(source)); } }