带反射和字符串的Java拼图
此源代码输出G'Day Mate。这是如何发生的带反射和字符串的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
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."));