0

我找到了这个线程这个 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"));
   }
}

上面的代码打印:

你好再见

为什么字符串litteral“Hello”在Parent类中引用“Bye bye”但在Child类中引用“Hello”?

4

1 回答 1

0

诸如字面量(“Hello”)、方法名称、导入的常量(public static final String)等字符串常量存储在当前类的常量池中。

在 Child 的 main 中,Parent 类被加载,静态字段被初始化。然后孩子从它的常量池中加载它的Hello并在其他情况下实习它,因为值不同。用途和检查-根据javadoc。String.internString.equalsString.value

您可以尝试一个 GrandPa 课程来解决跨课程的混乱情况。或者看到父母的问候与实习生的“再见”相同。尽管可能不再可以找到 Parent 的实习字符串,因为 hashCode 是错误的、过时的。可以创建一个具有相同哈希码的字符串。

于 2019-11-15T14:12:20.620 回答