它为示例代码中的以下两个打印语句打印true。据我了解,其按照 String 类的 equals 方法的逻辑如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
...
}
但我无法弄清楚他们的哈希码如何保持不变。 this == anObject这个条件和String类的hashCode方法有关系吗?如果是,那么它们如何相等。
请帮助我理解这一点。
确实可以通过反射来修改字符串的值(此时它会失去其不变性)。但在这种情况下,哈希码保持不变。为什么?
import java.lang.reflect.Field;
public class StringHacker {
public static void main(String[] args) throws Exception {
String myMonth = "January";
char[] yourMonth = {'M', 'a', 'y'};
Field value = String.class.getDeclaredField("value");
value.setAccessible(true);
value.set(myMonth, yourMonth);
System.out.println(myMonth.equals("January"));
System.out.println(myMonth.equals("May"));
}
}
输出为:
正确
正确
最佳答案
But in this case the hashcode remains unchanged. Why?
答案是 String::hashCode
将其结果缓存在私有(private)字段中。所以如果你这样做:
String s = /* create string */
int hash = s.hashcode();
/* use reflection to mutate string */
int hash2 = s.hashCode();
你会发现hash
和hash2
是相同的值。这只是为什么使用反射来改变字符串是一个坏主意的又一个原因。
(但是如果您阅读了String
的代码,您可以看到hashCode
是如何实现的,然后使用反射来清除缓存的hashcode值。)
关于java - 通过反射操作字符串及其对 equals 方法的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57290068/