带反射和字符串的Java拼图

带反射和字符串的Java拼图,java,reflection,puzzle,Java,Reflection,Puzzle,此源代码输出G'Day Mate。这是如何发生的 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 W

此源代码输出G'Day Mate。这是如何发生的

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("G'Day Mate."));
    } catch (Exception e) {
        throw new AssertionError(e);
    }
}
如果我们将主要函数“Hello World”更改为新字符串(“Hello World”):

它输出
Hello world


实际上发生了什么?

此源代码打开了一些有趣的java技术。让我们逐一检查

首先,我们需要了解代码的流程。代码的哪一部分将首先执行

静态初始化块。为什么?让我们咨询一下:

类的初始化包括执行其静态初始值设定项和类中声明的静态字段(类变量)的初始值设定项

什么时候发生?同样来自:

T是一个类,调用由T声明的静态方法

因此,我们可以得出这样的结论:静态initiazlier将在main方法之前首先执行

现在,这两条线正在使用反射:

Field value = String.class.getDeclaredField("value");
value.setAccessible(true);
为了简单起见,我们可以将第一行分成两行:

Class<String> c = String.class;
Field value = c.getDeclaredField("value");
如果深入研究,我们可以看到我们正在调用
集合(Object aoobject,Object value)
版本的
集合
value.get(“G'Day Mate.”)
正在返回
“G'Day Mate.”
字段的值,它实际上是一个
字符[]
。通过调用
set
,它将
“Hello World”
对象的值字段替换为
“G'Day Mate”。
对象的值字段

解释了
静态
块的代码

让我们深入了解主要功能。 这很简单。它应该输出
Hello,world
。但它正在输出G'Day Mate。为什么? 因为我们在
static
初始值设定项中创建的
Hello,world
字符串对象与我们在main函数中使用的
Hello,world
对象相同。再次咨询将有助于了解这一点

此外,字符串文字总是引用类字符串的同一实例。这是因为字符串文字(或者更一般地说,是常量表达式(§15.28)的值的字符串)被“插入”,以便使用string.intern方法共享唯一实例

这可以帮助你更简明地理解事实

所以它显示了不同的值,因为我们已经将对象的值更改为
G'Day,Mate

但如果在main函数中使用
newstring(“helloworld”)
,它将直接创建
String
的新实例,而不是签入其池。因此,main函数的
Hello-world
将不同于静态初始值设定项的
Hello-world
,因为
new String(“Hello-world”)
在堆中创建新对象,而不是在字符串常量池中使用先前创建的
“Hello-world”
对象

所以,如果你写

System.out.print(新字符串(“Hello World”).intern())


它将输出显示为
G'Day,Mate
。因为
intern()
方法在
fieldvalue=getDeclaredField(“value”)
处从
string常量池返回字符串实例的引用id,你的意思是
fieldvalue=c.getDeclaredField(“value”)
,我不知道你为什么问和回答这个问题。@OrelEraki Yup,那是一个打字错误。A关于询问和回答,这是为了将来reference@MD.SahibBinMahboob当我在java7中执行代码时,我发现下面给出的三条语句的输出都是相同的,即
G'Day,Mate
<代码>System.out.println(“你好世界”);System.out.println(新字符串(“Hello World”).intern();System.out.println(新字符串(“helloworld”)新字符串(“Hello World”)
将输出显示为
G'Day,Mate
Class<String> c = String.class;
Field value = c.getDeclaredField("value");
value.set("Hello World", value.get("G'Day Mate."));