对Java中HashCode方法的深入思考( 四 )


public static void main(String[] args) { Student student1 = new Student("小明", "male"); Student student2 = new Student("小明", "male");HashMap<Student, String> hashMap = new HashMap<>(); hashMap.put(student1, "小明"); String value = https://www.isolves.com/it/cxkf/yy/JAVA/2019-08-12/hashMap.get(student2); System.out.println(value); }复制代码输出结果
null复制代码得到的结果我们肯定不满意,这里的 student1 和 student2 虽然内存地址不同,但是它们的逻辑内容相同,我们认为它们应该是相同的 。
这里如果不好理解,猿友可以将 Student 类换成 String 类思考下,String 类是我们常常作为 HashMap 的 Key 值使用的,试想如果 String 类只重写了 equals 方法而没有重写 HashCode 方法,这里将某个字符串 new String("s") 作为 Key 然后 put 一个值,但是再根据 new String("s") 去 Get 的时候却得到 null 的结果,这是难以让人接受的 。
所以无论是理论的约定上还是实际编程中,我们重写 equals 方法的同时总要重写 hashCode 方法,请记住这点 。
虽然 hashCode 方法被重写了,但是如果我们想要获取原始的 Object 类中的哈希码,我们可以通过 System.identityHashCode(Object a)来获取,该方法返回默认的 Object 的 hashCode 方法值,即使对象的 hashCode 方法被重写了也不影响 。
public static native int identityHashCode(Object x);复制代码总结如果 HashCode 不是内存地址,那么 Java 中怎么获取内存地址呢?找了一圈发现没有直接可用的方法 。
后来想想也许这是 Java 语言编写者认为没有直接获取内存地址的必要吧,因为 Java 是一门高级语言相对于机器语言的汇编或者 C 语言来说更抽象并隐藏了复杂性,因为毕竟是在 C 和 C++ 的基础上进一步封装的 。而且由于自动垃圾回收机制和对象年龄代的问题,Java 中对象的地址是会变化的,因此获取实际内存地址的意义不大 。
当然以上是博主本人自己的观点,如果猿友有其他不同的意见或见解也可以留言,大家一起共同探讨 。




推荐阅读