1:首先看一下JDk API的观点
1-1:hashCode方法相关
1-2:identityHashCode()方法相关
2:此例的核心程序,对应的观点在注释中已经有所说明,请自己也动手实验一下看看!
import static java.lang.System.out; /** * 一个对象的hashCode和identityHashCode 的关系: * 1:对象的hashCode,一般是通过将该对象的内部地址转换成一个整数来实现的 * 2:当一个类没有重写Object类的hashCode()方法时,它的hashCode和identityHashCode是一致的 * 3:当一个类重写了Object类的hashCode()方法时,它的hashCode则有重写的实现逻辑决定,此时的hashCode值一般就不再和对象本身的内部地址有相应的哈希关系了 * 4:当null调用hashCode方法时,会抛出空指针异常,但是调用System.identityHashCode(null)方法时能正常的返回0这个值 * 5:一个对象的identityHashCode能够始终和该对象的内部地址有一个相对应的关系,从这个角度来讲,它可以用于代表对象的引用地址,所以,在理解==这个操作运算符的时候是比较有用的 * */ public class HashCodeTestMain { /** * 输出对象重写的hashCode和唯一的hashCode * @param object */ public static void printHashCodes(final Object object) { //输入对象的数据类型,以及调用toString()方法后返回的字符串形式,当对象为空时,此处输出null out.println(" The object type is : " + (object != null ? object.getClass().getName() : "null") + " The object value is : "+String.valueOf(object)); //输出对象的hashCode值,当对象为空时,此处输出N/A out.println("Overridden hashCode : " + (object != null ? object.hashCode() : "N/A")); //输出对象的identityHashCode值,如果对应的类没有重写Object类的hashCode()方法,则和默认的hashCode值一致 out.println("Identity hashCode : " + System.identityHashCode(object)); } /** * 主函数,程序执行的入口 * @param arguments */ public static void main(String[] arguments) { //基本数据类型的测试数据 final byte _byte = 6; final char _char = 's'; final short _short = 6; final int _int = 6; final long _long = 6L; final float _float = 6; final double _double= 6; final boolean _boolean = true; //包装类型的测试数据 final Byte _Byte = 9; final Character _Character = 'S'; final Short _Short = 9; final Integer _Integer = 9; final Long _Long = 9L; final Float _Float = 9F; final Double _Double = 9D; final Boolean _Boolean = false; //字符串类型的测试数据 final String someString = "someString"; //null final String nullString = null; //自定义的测试对象 final User user = new User(666,"godtrue"); //基本数据类型的测试数据 out.println(" 测试基本数据类型的数据"); printHashCodes(_byte); printHashCodes(_char); printHashCodes(_short); printHashCodes(_int); printHashCodes(_long); printHashCodes(_float); printHashCodes(_double); printHashCodes(_boolean); //包装类型的测试数据 out.println(" 测试包装数据类型的数据"); printHashCodes(_Byte); printHashCodes(_Character); printHashCodes(_Short); printHashCodes(_Integer); printHashCodes(_Long); printHashCodes(_Float); printHashCodes(_Double); printHashCodes(_Boolean); //字符串类型的测试数据 out.println(" 测试字符串类型的数据"); printHashCodes(someString); //null out.println(" 测试null空对象"); printHashCodes(nullString); //自定义的测试对象 out.println(" 测试自定义对象,构造此类的时候没有重写它的hashCode()方法"); printHashCodes(user); } }
3:User简单的自定义类,比较简单,没什么可讲的,关键是默认继承Object类,且没有重写hashCode()方法,不过重写了toString()方法
public class User { private Integer id; private String name; public User() { } public User(Integer id ,String name) { this.id = id; this.name = name; } @Override public String toString() { final StringBuffer sb = new StringBuffer("{"User":{"); sb.append(""id":"").append(id).append(""").append(","); sb.append(""name":"").append(name).append("""); sb.append("}}"); return sb.toString(); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
4:运行结果如下所示,不同的运行环境结果可能存在差异(win7+jdk7):
"C:Program FilesJavajdk1.7.0_71injava" -Didea.launcher.port=7532 "-Didea.launcher.bin.path=C:Program Files (x86)JetBrainsIntelliJ IDEA 2016.1.3in" -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.7.0_71jrelibcharsets.jar;C:Program FilesJavajdk1.7.0_71jrelibdeploy.jar;C:Program FilesJavajdk1.7.0_71jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.7.0_71jrelibextdnsns.jar;C:Program FilesJavajdk1.7.0_71jrelibextjaccess.jar;C:Program FilesJavajdk1.7.0_71jrelibextlocaledata.jar;C:Program FilesJavajdk1.7.0_71jrelibextsunec.jar;C:Program FilesJavajdk1.7.0_71jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.7.0_71jrelibextsunmscapi.jar;C:Program FilesJavajdk1.7.0_71jrelibextzipfs.jar;C:Program FilesJavajdk1.7.0_71jrelibjavaws.jar;C:Program FilesJavajdk1.7.0_71jrelibjce.jar;C:Program FilesJavajdk1.7.0_71jrelibjfr.jar;C:Program FilesJavajdk1.7.0_71jrelibjfxrt.jar;C:Program FilesJavajdk1.7.0_71jrelibjsse.jar;C:Program FilesJavajdk1.7.0_71jrelibmanagement-agent.jar;C:Program FilesJavajdk1.7.0_71jrelibplugin.jar;C:Program FilesJavajdk1.7.0_71jrelib esources.jar;C:Program FilesJavajdk1.7.0_71jrelib t.jar;D:workspace_testhello-worldoutproductionhello-world;C:Program Files (x86)JetBrainsIntelliJ IDEA 2016.1.3libidea_rt.jar" com.intellij.rt.execution.application.AppMain com.jd.test.equ.HashCodeTestMain 测试基本数据类型的数据 The object type is : java.lang.Byte The object value is : 6 Overridden hashCode : 6 Identity hashCode : 692191789 The object type is : java.lang.Character The object value is : s Overridden hashCode : 115 Identity hashCode : 748481924 The object type is : java.lang.Short The object value is : 6 Overridden hashCode : 6 Identity hashCode : 1923976189 The object type is : java.lang.Integer The object value is : 6 Overridden hashCode : 6 Identity hashCode : 1606535644 The object type is : java.lang.Long The object value is : 6 Overridden hashCode : 6 Identity hashCode : 732674977 The object type is : java.lang.Float The object value is : 6.0 Overridden hashCode : 1086324736 Identity hashCode : 397106541 The object type is : java.lang.Double The object value is : 6.0 Overridden hashCode : 1075314688 Identity hashCode : 1937943358 The object type is : java.lang.Boolean The object value is : true Overridden hashCode : 1231 Identity hashCode : 129543857 测试包装数据类型的数据 The object type is : java.lang.Byte The object value is : 9 Overridden hashCode : 9 Identity hashCode : 1842670188 The object type is : java.lang.Character The object value is : S Overridden hashCode : 83 Identity hashCode : 896176329 The object type is : java.lang.Short The object value is : 9 Overridden hashCode : 9 Identity hashCode : 1732745092 The object type is : java.lang.Integer The object value is : 9 Overridden hashCode : 9 Identity hashCode : 221024277 The object type is : java.lang.Long The object value is : 9 Overridden hashCode : 9 Identity hashCode : 1755797876 The object type is : java.lang.Float The object value is : 9.0 Overridden hashCode : 1091567616 Identity hashCode : 1122108505 The object type is : java.lang.Double The object value is : 9.0 Overridden hashCode : 1075970048 Identity hashCode : 76255581 The object type is : java.lang.Boolean The object value is : false Overridden hashCode : 1237 Identity hashCode : 1727296255 测试字符串类型的数据 The object type is : java.lang.String The object value is : someString Overridden hashCode : -1264993755 Identity hashCode : 984217639 测试null空对象 The object type is : null The object value is : null Overridden hashCode : N/A Identity hashCode : 0 测试自定义对象,构造此类的时候没有重写它的hashCode()方法 The object type is : com.jd.test.equ.User The object value is : {"User":{"id":"666","name":"godtrue"}} Overridden hashCode : 1826809479 Identity hashCode : 1826809479 Process finished with exit code 0
5:上面的代码和注释已经抛出了我的观点,代码相对简单,可能还有一些繁琐,不过经过对比更能体现出自己观点的正确性,原本是想写一篇关于==操作符相关的博文的,后来发现要能清楚某些知识点,就需要先弄明白另外一些知识点,经过试验和查阅资料就有了此篇博文了,后续再补上相关联的知识点小结。