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

为什么Object.hashCode()在运行中返回相同的值

如何解决《为什么Object.hashCode()在运行中返回相同的值》经验,为你挑选了2个好方法。

hashCode()HotSpot 的默认实现返回一个随机值并将其存储在对象头中.这在Java 8中似乎没有改变,其中哈希值是通过调用来计算的os::random():

static inline intptr_t get_next_hash(Thread * Self, oop obj) {
  intptr_t value = 0 ;
  if (hashCode == 0) {
     // This form uses an unguarded global Park-Miller RNG,
     // so it's possible for two threads to race and generate the same RNG.
     // On MP system we'll have lots of RW access to a global, so the
     // mechanism induces lots of coherency traffic.
     value = os::random() ;
  } else
...

我想知道为什么hashCode()在关闭JVM之后不断返回相同的值,我通过执行下面的简单测试,重新启动机器然后main()再次运行来尝试.

public class SimpleTest {
  public static void main(String[] args) {
    Object obj = new Object();
    // This calls toString() which calls hashCode() which calls os::random()
    System.out.println(obj);
  }
}

如果hashCode()实际上每次输出如何相同os::random()


java -version

java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b25)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)

注意:

如果有人问自己是什么System.out.println(obj);,它调用 obj.toString()该对象是否非空,产生类似java.lang.Object@659e0bfd,有做hashCode():后一部分@是对象的散列码十六进制(和是无关的,在内存中的对象的位置,相反给什么文件表明,这导致了误解).



1> David Schwar..:

确定性行为使代码更容易调试,因为它可以被复制.所以实现倾向于在可能的情况下选择.想象一下,如果哈希每次都不同,那么复制一些由于错误处理哈希冲突而失败的单元测试(例如,在哈希长度缩短之后)是多么困难.


这似乎不是一个很好的理由; 如果您正在编写依赖于`.hashCode()`行为的测试,那么您应该测试已明确定义`.hashCode()`方法的对象.依靠`Object.hashCode()`保持稳定只会引发问题,特别是升级JVM版本时.如果有的话,这是一个在运行之间显式地使`Object.hashCode()`volatile的参数.

2> dimo414..:

要回答你的问题,我们首先要问第二个问题,"为什么os::random()种子会固定种子?"

正如@DavidSchwartz所说,拥有一个带有固定种子的"随机"数字生成器非常有用,因为它可以为您提供任意但确定的行为.JVM开发人员可以调用os::random()并且仍然知道JVM的行为不依赖于任何外部因素.除了其他好处之外,这意味着JVM测试是可重复的; 使用"适当"种子RNG将难以重现与RNG相关的故障.

现在我们可以回答原来的问题,改写为"为什么HotSpot的实现Object.hashCode()使用os::random()?"

这个问题的答案很可能只是因为它很简单,而且很有效.哈希码需要分布均匀,这是RNG提供的.JVM的这个区域中最简单,最容易访问的RNG是os::random().由于Object.hashCode()不能保证这些值的来源,因此根本不是os::random()随机的并不重要.

您会注意到这只是一种可能的散列策略,其他几种定义(并由hashCode全局选择),包括它们" 可能会成为......未来版本中的默认值 ".

最终,这只是一个实现细节.没有必要更积极地随机化Object.hashCode(),并且完全有可能其他JVM不这样做,或者其他操作系统表现不同.实际上,在Eclipse中,我反复运行代码时会看到不同的哈希码.此外,合同Object.hashCode()建议典型的JVM实现根本不实现Object.hashCode()这种方式:

这通常通过将对象的内部地址转换为整数来实现


另请注意,您的测试仅验证第一次调用.hashCode()是否一致.在任何类型的多线程程序中,您都不能指望这种行为.它还可以os::random()在执行期间依赖于JVM调用中的任何其他内容,它可以随时执行(例如,如果垃圾收集器在第一个GC将是非确定性之后依赖于调用os::random()的结果.hashCode()).


推荐阅读
  • 本文将详细探讨 Java 中提供的不可变集合(如 `Collections.unmodifiableXXX`)和同步集合(如 `Collections.synchronizedXXX`)的实现原理及使用方法,帮助开发者更好地理解和应用这些工具。 ... [详细]
  • 深入理解Redis的数据结构与对象系统
    本文详细探讨了Redis中的数据结构和对象系统的实现,包括字符串、列表、集合、哈希表和有序集合等五种核心对象类型,以及它们所使用的底层数据结构。通过分析源码和相关文献,帮助读者更好地理解Redis的设计原理。 ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • 深入解析SpringMVC核心组件:DispatcherServlet的工作原理
    本文详细探讨了SpringMVC的核心组件——DispatcherServlet的运作机制,旨在帮助有一定Java和Spring基础的开发人员理解HTTP请求是如何被映射到Controller并执行的。文章将解答以下问题:1. HTTP请求如何映射到Controller;2. Controller是如何被执行的。 ... [详细]
  • 本文探讨了如何在Classic ASP中实现与PHP的hash_hmac('SHA256', $message, pack('H*', $secret))函数等效的哈希生成方法。通过分析不同实现方式及其产生的差异,提供了一种使用Microsoft .NET Framework的解决方案。 ... [详细]
  • 深入剖析JVM垃圾回收机制
    本文详细探讨了Java虚拟机(JVM)中的垃圾回收机制,包括其意义、对象判定方法、引用类型、常见垃圾收集算法以及各种垃圾收集器的特点和工作原理。通过理解这些内容,开发人员可以更好地优化内存管理和程序性能。 ... [详细]
  • 在 Flutter 开发过程中,开发者经常会遇到 Widget 构造函数中的可选参数 Key。对于初学者来说,理解 Key 的作用和使用场景可能是一个挑战。本文将详细探讨 Key 的概念及其应用场景,并通过实例帮助你更好地掌握这一重要工具。 ... [详细]
  • 本文详细介绍了如何准备和安装 Eclipse 开发环境及其相关插件,包括 JDK、Tomcat、Struts 等组件的安装步骤及配置方法。 ... [详细]
  • 不确定性|放入_华为机试题 HJ9提取不重复的整数
    不确定性|放入_华为机试题 HJ9提取不重复的整数 ... [详细]
  • 在Java中,this是一个引用当前对象的关键字。如何通过this获取并显示其所指向的对象的属性和方法?本文详细解释了this的用法及其背后的原理。 ... [详细]
  • 对象自省自省在计算机编程领域里,是指在运行时判断一个对象的类型和能力。dir能够返回一个列表,列举了一个对象所拥有的属性和方法。my_list[ ... [详细]
  • 本文详细解析了Java中hashCode()和equals()方法的实现原理及其在哈希表结构中的应用,探讨了两者之间的关系及其实现时需要注意的问题。 ... [详细]
  • 本文探讨了在Java中如何正确地将多个不同的数组插入到ArrayList中,避免所有数组在插入后变得相同的问题。我们将分析代码中的问题,并提供解决方案。 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 并发编程 12—— 任务取消与关闭 之 shutdownNow 的局限性
    Java并发编程实践目录并发编程01——ThreadLocal并发编程02——ConcurrentHashMap并发编程03——阻塞队列和生产者-消费者模式并发编程04——闭锁Co ... [详细]
author-avatar
谢海武181_160
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有