hashCode和identityHashCode 的關系


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:上面的代碼和注釋已經拋出了我的觀點,代碼相對簡單,可能還有一些繁瑣,不過經過對比更能體現出自己觀點的正確性,原本是想寫一篇關於==操作符相關的博文的,后來發現要能清楚某些知識點,就需要先弄明白另外一些知識點,經過試驗和查閱資料就有了此篇博文了,后續再補上相關聯的知識點小結。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM