Java的Object.hashCode()的返回值到底是不是对象内存地址?
关于这个问题,查阅了网上的资料,发现证明过程太繁琐,这里我用了反证法。
java.lang.Object.hashCode()的返回值到底是不是对象内存地址?
hashCode契约
说到这个问题,大家的第一反应一定和我一样——去查Object.hashCode的源码,但翻开源码,看到的却是这样的(Oracle JDK 8):
/**
* Returns a hash code value for the object. This method is
* supported for the benefit of hash tables such as those provided by
* {@link java.util.HashMap}.
* <p>
* The general contract of {@code hashCode} is:
* <ul>
* <li>Whenever it is invoked on the same object more than once during
* an execution of a Java application, the {@code hashCode} method
* must consistently return the same integer, provided no information
* used in {@code equals} comparisons on the object is modified.
* This integer need not remain consistent from one execution of an
* application to another execution of the same application.
* <li>If two objects are equal according to the {@code equals(Object)}
* method, then calling the {@code hashCode} method on each of
* the two objects must produce the same integer result.
* <li>It is <em>not</em> required that if two objects are unequal
* according to the {@link java.lang.Object#equals(java.lang.Object)}
* method, then calling the {@code hashCode} method on each of the
* two objects must produce distinct integer results. However, the
* programmer should be aware that producing distinct integer results
* for unequal objects may improve the performance of hash tables.
* </ul>
* <p>
* As much as is reasonably practical, the hashCode method defined by
* class {@code Object} does return distinct integers for distinct
* objects. (This is typically implemented by converting the internal
* address of the object into an integer, but this implementation
* technique is not required by the
* Java™ programming language.)
*
* @return a hash code value for this object.
* @see java.lang.Object#equals(java.lang.Object)
* @see java.lang.System#identityHashCode
*/
public native int hashCode();
Object.hashCode()是一个native方法,看不到源码(Java代码,Oracle的JDK是看不到的,OpenJDK或其他开源JRE是可以找到对应的C/C++代码)。
上面这段注释指出了Object.hashCode()在JRE(JavaRuntime Library)中应该遵循的一些契约(contract):
(PS:所谓契约当然是大家一致达成的,各个JVM厂商都会遵循)
(1)一致性(consistent),在程序的一次执行过程中,对同一个对象必须一致地返回同一个整数。
(2)如果两个对象通过equals(Object)比较,结果相等,那么对这两个对象分别调用hashCode方法应该产生相同的整数结果。(PS:这里equals和hashCode说的都是Object类的)
(3)如果两个对象通过java.lang.Object.equals(java.lang.Ojbect)比较,结果不相等,不必保证对这两个对象分别调用hashCode()也返回两个不相同的整数
因为每个对象的内存地址都是不一样的,如果hashCode()的返回值是对象内存地址,那么两个对象分别调用hashCode()方法将会返回两个截然不同的整数,这与契约三矛盾了,因此java.lang.Object.hashCode()的返回值不是对象内存地址!
在这里我觉得hashCode()方法的返回值是对象内存地址通过hash算法计算之后的哈希码值,因此才会出现两个对象分别调用hashCode()返回同一个值。
Java的Object.hashCode()的返回值到底是不是对象内存地址?的更多相关文章
- C++ 赋值构造函数的返回值到底有什么用?且返回值是否为引用类型有什么区别吗?
首先定义类Person class Person{ public: string name; Person()=default; //默认构造函数 Person(string nam):name(na ...
- JAVA 框架 springmvc controller的返回值
一.返回值:ModleView对象. 使用modelAndView.setViewName设置返回的页面.使用modelAndView.addObject设置返回的数据. @RequestMappin ...
- hashCode竟然不是根据对象内存地址生成的?还对内存泄漏与偏向锁有影响?
起因 起因是群里的一位童鞋突然问了这么问题: 如果重写 equals 不重写 hashcode 会有什么影响? 这个问题从上午10:45 开始陆续讨论,到下午15:39 接近尾声 (忽略这形同虚设的马 ...
- python与java的内存机制不一样;java的方法会进入方法区直到对象消失 方法才会消失;python的方法是对象每次调用都会创建新的对象 内存地址都不i一样
python与java的内存机制不一样;java的方法会进入方法区直到对象消失 方法才会消失;python的方法是对象每次调用都会创建新的对象 内存地址都不i一样
- java hashCode方法返回值
hashCode 是和内存地址相关的一个整数. HashCode只是在需要用到哈希算法的数据结构中才有用 用途是为了方便快速地查找对象: HashMap 是根据键对象的 HashCode 来进行快速查 ...
- java matlab混合编程之返回值Struct类型
java matlab混合编程的时候当返回值是Struct类型(matlab中的返回类型)如何来取得(java中)其值? 上网找,看到这个网页:http://www.mathworks.cn/cn/h ...
- Java中Object.hashCode contract
面试时在这个问题上犯了个错误,只重写了equals方法,而没有覆盖hashCode()方法. 回来重读了Effective Java的Item 9,里面提到Object.hashCode contra ...
- Java多线程-新特性-有返回值的线程
在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了. 现在Java终于有可返回值的任务(也可以叫做线程)了. 可返回值的任务必须实现 ...
- JAVA多线程解惑之多线程返回值
如果有人问题你,多线程可以有返回值吗?你怎么回答? 看下面例子,我定义了一个类实现了Callable 接口 public class MyCallable implements Callable< ...
随机推荐
- Struts2学习笔记(OGNL表达式)
Struts 2支持以下几种表达式语言: OGNL(Object-Graph Navigation Language),可以方便地操作对象属性的开源表达式语言: JSTL(JSP Standard T ...
- hdu 5044 树区间操作最后输出/ lca+dfs
题意:一棵树,俩种操作:1 有路径上的全部点加vi,2全部边加vi. 先离线求出全部询问的lca,再遍历询问一次,点+vi,lca-2*vi ,最后dfs从叶子扫上来一次,最后再祖先点补上就可以.用了 ...
- tomcat日志神器--kibana
最近公司搭了套kibana的日志系统,感受比原来查看日志方便多了.记得以前查看日志是通过ssh到服务器,查看系统日志用vi查看器查看或者下载到本地,用logview查看搜索,可读性很低.自从用了kib ...
- 函数preg_replace()与str_replace()
如截图,preg_replace()的用法 <?php $str="as2223adfsf0s4df0sdfsdf"; echo preg_replace("/0/ ...
- jQuery-处理css样式
1.css方法 获取匹配元素集合中的第一个元素的样式属性的值 或 设置每个匹配元素的一个或多个CSS属性 1)获取并设置单个css值 jQuery对象.css('css属性'); jQuery对象.c ...
- mybatis由浅入深day02_3一对多查询
3 一对多查询 3.1 需求(查询订单及订单明细的信息) 查询订单及订单明细的信息. 3.2 sql语句 确定主查询表:订单表 确定关联查询表:订单明细表 在一对一查询基础上添加订单明细表关联即可. ...
- Serlvet学习笔记之二—不同页面共享数据
一共有四种方法实现共享页面共享数据 1.cookie 2.sendRedirect 3.session 4.隐藏表单提交(form) 5.ServletContex 1.cookie:服务器在客户端保 ...
- 安装配置博客WordPress
1.下载并解压WordPress cd /usr/local/src wget https://cn.wordpress.org/wordpress-4.4.2-zh_CN.tar.gztar zcv ...
- Unity版本与虚拟现实头盔Deepoon大朋版本测试
一.看这里 Unity官方与OC runtime版本兼容性说明: https://developer.oculus.com/documentation/game-engines/latest/conc ...
- Unity随机Prefab,自动前往某点处理
对与U3D AI,看了下,自己做了小功能,以备后用啊! 一,在某区域随机产生某个对象 C# 文件名称为RadomAPoint.cs using UnityEngine; using System.C ...