java - 通过反射操作字符串及其对 equals 方法的影响

标签 java

它为示例代码中的以下两个打印语句打印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();

你会发现hashhash2是相同的值。这只是为什么使用反射来改变字符串是一个坏主意的又一个原因。

(但是如果您阅读了String的代码,您可以看到hashCode是如何实现的,然后使用反射来清除缓存的hashcode值。)

关于java - 通过反射操作字符串及其对 equals 方法的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57290068/

相关文章:

java - 使用 <fmt :setLocale value ="en_GB"/> 未将默认区域设置设置为英国

java - 使用 Ant 和 Eclipse 创建 Struts 1.X 项目

java - 如何找到已编译类的目标 Java 版本?

java - 既是 Set 又是 List(序列)的 List 实现?

java - 如何根据变量选择同一个表的不同数据

java - Android - 使 Activity 根据点击的内容显示不同的内容

java - 您将 JPopupMenu 的逻辑存储在哪里?

java - hornetq "listMessagesAsJson"不工作

java - ant 通过 npm 安装 - 需要 node 0.8.0+ 但安装失败?

java - 关于何时应该将直接缓冲区与 Java NIO 一起用于网络 I/O 的简单规则?