热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java对象的默认hashCode()实现

如何解决《Java对象的默认hashCode()实现》经验,为你挑选了2个好方法。

我试图理解Java的Object的hashCode(),并看到Java Object的hashCode()方法的以下代码:

package java.lang;
public class Object {

 // Some more code

 public native int hashCode();

 // Some other code

}
现在,我们知道如果我们创建一个类,它会隐式扩展Object类,为此,我编写了一个示例示例:
package com.example.entity;
public class FirstClass {
    private int id;
    private String name;
    // getters and setters
}

所以,这个类即:隐式FirstClass扩展Object类.

主要课程:
package com.example.app.main;
import com.example.entity.FirstClass;
    public class MainApp {
        public static void main(String[] args) {
             FirstClass fs = new FirstClass();
             fs.setId(1);
             fs.setName("TEST");
             System.out.println("The hasCode for object fs is " + fs.hashCode());
         }
 }

正如隐式FirstClass扩展Object类一样,因此它将具有Object类的hashCode()方法.

我调用了hashCode()on FirstClass对象,因为我没有覆盖它hashCode(),理论上它应该调用ObjecthashCode().

我的疑问是:

由于Object类没有任何实现,如何计算任何对象的哈希码?

在我的例子中,当我运行程序时,它返回的哈希码是366712642.

任何人都可以帮我理解这个吗?



1> Eugene..:

虽然这里有一些答案表明默认实现是基于"内存"的,但这是完全错误的.现在很多年情况并非如此.

在java-8下,你可以这样做:

java -XX:+PrintFlagsFinal | grep hashCode

获取使用的确切算法(5默认).

  0 == Lehmer random number generator, 
  1 == "somehow" based on memory address
  2 ==  always 1
  3 ==  increment counter 
  4 == memory based again ("somehow")
  5 == read below

默认情况下(5),它使用的是Marsaglia XOR-Shift算法,它与内存无关.

如果您这样做,这不是很难证明:

 System.out.println(new Object().hashCode());

多次,在一个新的VM中 - 你将获得相同的值,因此Marsaglia XOR-Shift以种子开始(总是相同,除非其他一些代码不会改变它)并从中开始工作.

但即使你切换到一些基于内存的hashCode,而Objects可能会四处移动(Garbage Collector调用),你如何确保 GC移动这个对象采取相同的hashCode ?提示:indentityHashCode和Object标头.


@CuriousMind哦那一个.它只打印JVM具有的所有标志及其默认值...
永远不会停止学习.将看到我可以做些什么来更新我的答案更准确.

2> GhostCat say..:

您弄错了:

public native int hashCode();

并不意味着没有实现。这仅表示该方法是在JVM 的本地 C / C ++部分中实现的。这意味着您找不到该方法的Java源代码。但是,每当您调用hashCode()某个对象时,JVM内仍有一些代码会被调用。

正如另一个答案所解释的那样:“默认”实现使用了基础对象的“内存”地址。事情是:使用java意味着没有“内存地址”的知识。请记住:JVM是用C / C ++编写的- 真正的内存管理发生在JVM的这些本机部分中。

换句话说:您不能编写Java代码来告诉您对象的“本机内存地址”。

但是正如Eugene的另一个答案所表明的那样:关于“内存位置”的散列已经成为过去。


@Eugene`Object.hashCode` * still *的规范提到了对象的地址,这会引起误解。我已提交[JDK-8199394](https://bugs.openjdk.java.net/browse/JDK-8199394)来解决此问题。
@Eugene这里有两个方面。由于对象的内存地址可以在垃圾回收器移动它们时更改,因此一旦查询后,它们必须以某种方式记住其报告的哈希码。但是,问题是,如果仍然可以访问对象,则在线程的TLAB(即相同的内存区域)中创建对象,然后再将其移动到幸存者空间。因此,使用基于内存的哈希码将承担具有非常接近的值的风险(哈希分布不佳)。
推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 本文介绍了安全性要求高的真正密码随机数生成器的概念和原理。首先解释了统计学意义上的伪随机数和真随机数的区别,以及伪随机数在密码学安全中的应用。然后讨论了真随机数的定义和产生方法,并指出了实际情况下真随机数的不可预测性和复杂性。最后介绍了随机数生成器的概念和方法。 ... [详细]
  • 颜色迁移(reinhard VS welsh)
    不要谈什么天分,运气,你需要的是一个截稿日,以及一个不交稿就能打爆你狗头的人,然后你就会被自己的才华吓到。------ ... [详细]
  • 在本教程中,我们将看到如何使用FLASK制作第一个用于机器学习模型的RESTAPI。我们将从创建机器学习模型开始。然后,我们将看到使用Flask创建AP ... [详细]
author-avatar
王言
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有