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("\nThe object type is : " + (object != null ? object.getClass().getName() : "null") + "\nThe 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("\n測試基本數據類型的數據"); printHashCodes(_byte); printHashCodes(_char); printHashCodes(_short); printHashCodes(_int); printHashCodes(_long); printHashCodes(_float); printHashCodes(_double); printHashCodes(_boolean); //包裝類型的測試數據 out.println("\n測試包裝數據類型的數據"); printHashCodes(_Byte); printHashCodes(_Character); printHashCodes(_Short); printHashCodes(_Integer); printHashCodes(_Long); printHashCodes(_Float); printHashCodes(_Double); printHashCodes(_Boolean); //字符串類型的測試數據 out.println("\n測試字符串類型的數據"); printHashCodes(someString); //null out.println("\n測試null空對象"); printHashCodes(nullString); //自定義的測試對象 out.println("\n測試自定義對象,構造此類的時候沒有重寫它的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 Files\Java\jdk1.7.0_71\bin\java" -Didea.launcher.port=7532 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2016.1.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.7.0_71\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\jce.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\jfxrt.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\resources.jar;C:\Program Files\Java\jdk1.7.0_71\jre\lib\rt.jar;D:\workspace_test\hello-world\out\production\hello-world;C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2016.1.3\lib\idea_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:上面的代碼和注釋已經拋出了我的觀點,代碼相對簡單,可能還有一些繁瑣,不過經過對比更能體現出自己觀點的正確性,原本是想寫一篇關於==操作符相關的博文的,后來發現要能清楚某些知識點,就需要先弄明白另外一些知識點,經過試驗和查閱資料就有了此篇博文了,后續再補上相關聯的知識點小結。