我找到了这个线程这个Java代码片段是如何工作的?(字符串池和反射(谈论使用反射更改字符串的值。
我完全理解这个技巧,但做了一些小改动后,效果就不如预期了。
你能解释一下这个代码中发生了什么吗?
import java.lang.reflect.Field;
public class Parent {
static String hello = "Hello";
static {
try {
Field value = hello.getClass().getDeclaredField("value");
value.setAccessible(true);
value.set(hello, "Bye bye".toCharArray());
} catch (Exception e) {
e.printStackTrace();
}
}
public static boolean check(String s){
System.out.println(s + " " + "Hello");
return s.equals("Hello");
}
}
public class Child extends Parent{
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
System.out.println(check("Hello"));
}
}
以上代码打印:
你好,再见
false
为什么字符串"Hello"在Parent类中指代"Bye Bye",而在Child类中指指代"你好"?
字符串常量,如文本("Hello"(、方法名、导入的常量(public static final String(等,都存储在当前类的常量池中。
在Child的main中,加载Parent类,初始化静态字段。然后,子级从其常量池加载的Hello,并在其他情况下实习,因为值不同。String.intern
使用String.equals
,并根据javadoc检查String.value
。
你可以试着上爷爷的课,以避免课堂上的混乱。或者,家长的问候与实习的"再见"完全相同。尽管可能由于hashCode是错误的、过时的,Parent的内部字符串不再可找到。可以创建一个具有相同哈希代码的字符串。