一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - Java 基礎(chǔ) | Object 源碼解析

Java 基礎(chǔ) | Object 源碼解析

2020-12-01 22:53今日頭條一角錢技術(shù) Java教程

Java 是一門面向?qū)ο蟮恼Z言,在 Java 里面一切都可以看作是一個對象,而 Java 里面所有的對象都默認繼承于 Object 類。

Java 基礎(chǔ) | Object 源碼解析

前言

Java 是一門面向?qū)ο蟮恼Z言,在 Java 里面一切都可以看作是一個對象,而 Java 里面所有的對象都默認繼承于 Object 類。

本文基于JDK1.8

Java 基礎(chǔ) | Object 源碼解析

可以看到一共12個方法,其中 registerNatives() 是 native 修飾的,一個本地方法,具體是用C(C++)在DLL中實現(xiàn)的,然后通過JNI調(diào)用。

getClass

public final native Class getClass(); 

getClass 也是個 native 方法,這個方法的作用就是返回某個對象的運行時類,它的返回值是 Class 類型,Class c = obj.getClass();通過對象 c ,我們可以獲取該對象的所有成員方法,每個成員方法都是一個 Method 對象;我們也可以獲取該對象的所有成員變量,每個成員變量都是一個 Field 對象;同樣的,我們也可以獲取該對象的構(gòu)造函數(shù),構(gòu)造函數(shù)則是一個 Constructor 對象。這個方法在反射時會常用到。

hashCode

public native int hashCode(); 

  • hashCode 方法返回散列值。
  • 返回值默認是由對象的地址轉(zhuǎn)換而來的。
  • 同一個對象調(diào)用 hashCode 的返回值是相等的。
  • 兩個對象的 equals 相等,那 hashCode 一定相等。
  • 兩個對象的 equals 不相等,那 hashCode 也不一定相等。

equals

public boolean equals(Object obj) { 

    return (this == obj); 

equals 的實現(xiàn)非常簡單,它的作用就是比較兩個對象是否相等,而比較的依據(jù)就是二者的內(nèi)存地址。除此之外,equals 還遵循以下幾個原則:

1、自反性:x.equals(x);  // true 

2、對稱性:x.equals(y) == y.equals(x);  // true 

3、傳遞性:if (x.equals(y) && y.equals(z)) 

            x.equals(z); // true

4、一致性,只要對象沒有被修改,多次調(diào)用 equals() 方法結(jié)果不變: 

x.equals(y) == x.equals(y); // true  

5、非空性,對任何不是 null 的對象 x 調(diào)用 x.equals(null) 結(jié)果都為 false : 

x.equals(null); // false

為什么要重寫 hashcode 和 equals ?

因為這兩個方法都跟對象的比較有關(guān),所以如果在程序中要做對象比較,那大概率要重寫這兩個方法了。因為equals默認的比較邏輯就是對象的地址進行比較,兩個對象內(nèi)存地址肯定不同,所以無論如何兩個對象通過eqals比較肯定返回false。

但在實際編程中,我們經(jīng)常會遇到去重,或者將對象放到有序集合中,或者將對象存入無重復的集合中,這時如果沒有重寫equals和hashCode,則無法達到需求。

舉個例子,系統(tǒng)中同時存在兩個對象,對象A和對象B,其姓名和身份證號一模一樣。此時,在系統(tǒng)內(nèi)存中是兩個對象,但其內(nèi)容一致分明是一個人同時產(chǎn)生了兩條重復信息。如果使用默認的equals方法比較,則這兩個對象永遠不相等,永遠不能比出來是一條相同的重復信息。所以,要重寫equals和hashCode方法來達到以上需求效果。

clone

protected native Object clone() throws CloneNotSupportedException; 

clone() 是 Object 的 protected 方法,它不是 public,一個類不顯式去重寫 clone(),其它類就不能直接去調(diào)用該類實例的 clone() 方法。此外,Clone 的注釋中還提到比較重要的幾點:

  • 克隆的對象必須要實現(xiàn) Cloneable 接口并重寫 clone 方法,否則會報 CloneNotSupportedException 異常
  • clone() 方法并不是 Cloneable 接口的方法,而是 Object 的一個 protected 方法。Cloneable 接口只是規(guī)定,如果一個類沒有實現(xiàn) Cloneable 接口又調(diào)用了 clone() 方法,就會拋出 CloneNotSupportedException。
  • 淺拷貝:拷貝對象和原始對象的引用類型引用同一個對象。
  • 深拷貝:拷貝對象和原始對象的引用類型引用不同對象。

關(guān)于淺拷貝與深拷貝我們后面再討論。

toString

public String toString() { 

 return getClass().getName() + "@" + Integer.toHexString(hashCode()); 

返回該對象的字符串表示,非常重要的方法

  • getClass().getName(); 獲取字節(jié)碼文件的對應全路徑名例如java.lang.Object;
  • Integer.toHexString(hashCode()); 將哈希值轉(zhuǎn)成16進制數(shù)格式的字符串。

wait 和 notify

public final void wait() throws InterruptedException { 

     wait(0); 

 

public final native void wait(long timeout) throws InterruptedException; 

 

public final void wait(long timeout, int nanos) throws InterruptedException { 

        if (timeout < 0) { 

            throw new IllegalArgumentException("timeout value is negative"); 

        } 

 

        if (nanos < 0 || nanos > 999999) { 

            throw new IllegalArgumentException( 

                                "nanosecond timeout value out of range"); 

        } 

 

        if (nanos > 0) { 

            timeout++; 

        } 

 

        wait(timeout); 

wait 的作用是讓當前線程進入等待狀態(tài),同時,wait() 也會讓當前線程釋放它所持有的鎖。直到其他線程調(diào)用此對象的 notify() 方法或 notifyAll() 方法,當前線程被喚醒進入就緒狀態(tài)。

wait(long timeout) (以毫秒為單位)讓當前線程處于等待(阻塞)狀態(tài),直到其他線程調(diào)用此對象的notify() 方法或 notifyAll() 方法,或者超過指定的時間量,當前線程被喚醒進入就緒狀態(tài)。

wait(long timeout, int nanos) 和 wait(long timeout) 功能一樣,唯一的區(qū)別是這個可以提供更高的精度。總超時時間(以納秒為單位)計算為 1000000 *timeout+ nanos。By the way ,wait(0,0) 和 wait(0) 效果一樣。

ublic final native void notify(); 

public final native void notifyAll(); 

首先是 notify ,notify 的作用就是隨機喚醒在等待隊列的某個線程,而 notifyAll 就是喚醒在等待隊列的所有線程。

注意:notify 和 wait 方法的使用規(guī)范。意思就是這二者必須在 synchronized 修飾的同步方法或同步代碼中使用。

Thread.sleep() 和 Object.wait() 有什么區(qū)別?

首先,二者都可以暫停當前線程,釋放 CPU 控制權(quán)。主要的區(qū)別在于 Object.wait()在釋放 CPU 同時,釋放了對象鎖的控制。而 Thread.sleep() 沒有對鎖釋放。換句話說 sleep 就是耍流氓,占著茅坑不拉屎。

完整代碼

package java.lang; 

 

 

public class Object { 

 

    /** 

     * 一個本地方法,具體是用C(C++)在DLL中實現(xiàn)的,然后通過JNI調(diào)用 

     */ 

    private static native void registerNatives(); 

 

    /** 

     * 對象初始化時自動調(diào)用此方法 

     */ 

    static { 

        registerNatives(); 

    } 

 

    /** 

     * 返回此Object的運行時類 

     */ 

    public final native Class<?> getClass(); 

 

    /** 

     * hashCode的常規(guī)協(xié)定是: 

     * 1.在java應用程序執(zhí)行期間,在對同一對象多次調(diào)用hashCode()方法時,必須一致地返回相同的整數(shù),前提是將對象進行equals比較時所用的信息沒有被修改。 

     * 從某一應用程序的一次執(zhí)行到同一應用程序的另一次執(zhí)行,該整數(shù)無需保持一致。 

     * 2.如果根據(jù)equals(object)方法,兩個對象是相等的,那么對這兩個對象中的每個對象調(diào)用hashCode方法都必須生成相同的整數(shù)結(jié)果。 

     * 3.如果根據(jù)equals(java.lang.Object)方法,兩個對象不相等,那么對這兩個對象中的任一對象上調(diào)用hashCode()方法不要求一定生成不同的整數(shù)結(jié)果。 

     * 但是,程序員應該意識到,為不相等的對象生成不同整數(shù)結(jié)果可以提高哈希表的性能。 

     */ 

    public native int hashCode(); 

 

    /** 

     * 這里比較的是對象的內(nèi)存地址 

     */ 

    public boolean equals(Object obj) { 

        return (this == obj); 

    } 

 

    /** 

     * 本地clone方法,用于對象的復制 

     */ 

    protected native Object clone() throws CloneNotSupportedException; 

 

    /** 

     * 返回該對象的字符串表示,非常重要的方法 

     * getClass().getName();獲取字節(jié)碼文件的對應全路徑名例如java.lang.Object 

     * Integer.toHexString(hashCode());將哈希值轉(zhuǎn)成16進制數(shù)格式的字符串。 

     */ 

    public String toString() { 

        return getClass().getName() + "@" + Integer.toHexString(hashCode()); 

    } 

 

    /** 

     * 不能被重寫,用于喚醒一個在因等待該對象(調(diào)用了wait方法)被處于等待狀態(tài)(waiting 或 time_wait)的線程,該方法只能同步方法或同步塊中調(diào)用 

     */ 

    public final native void notify(); 

 

    /** 

     * 不能被重寫,用于喚醒所有在因等待該對象(調(diào)用wait方法)被處于等待狀態(tài)(waiting或time_waiting)的線程,該方法只能同步方法或同步塊中調(diào)用 

     */ 

    public final native void notifyAll(); 

 

    /** 

     * 不能被重寫,用于在線程調(diào)用中,導致當前線程進入等待狀態(tài)(time_waiting),timeout單位為毫秒,該方法只能同步方法或同步塊中調(diào)用,超過設(shè)置時間后線程重新進入可運行狀態(tài) 

     */ 

    public final native void wait(long timeout) throws InterruptedException; 

 

 

    public final void wait(long timeout, int nanos) throws InterruptedException { 

        if (timeout < 0) { 

            throw new IllegalArgumentException("timeout value is negative"); 

        } 

 

        if (nanos < 0 || nanos > 999999) { 

            throw new IllegalArgumentException( 

                    "nanosecond timeout value out of range"); 

        } 

 

        if (nanos > 0) { 

            timeout++; 

        } 

 

        wait(timeout); 

    } 

 

    /** 

     * 在其他線程調(diào)用此對象的notify()方法或notifyAll()方法前,導致當前線程等待。換句話說,此方法的行為就好像它僅執(zhí)行wait(0)調(diào)用一樣。 

     * 當前線程必須擁有此對象監(jiān)視器。 

     * 該線程發(fā)布對此監(jiān)視器的所有權(quán)并等待,直到其他線程通過調(diào)用notify方法或notifyAll方法通知在此對象的監(jiān)視器上等待的線程醒來, 

     * 然后該線程將等到重新獲得對監(jiān)視器的所有權(quán)后才能繼續(xù)執(zhí)行。 

     */ 

    public final void wait() throws InterruptedException { 

        wait(0); 

    } 

 

    /** 

     * 這個方法用于當對象被回收時調(diào)用,這個由JVM支持,Object的finalize方法默認是什么都沒有做,如果子類需要在對象被回收時執(zhí)行一些邏輯處理,則可以重寫finalize方法。 

     */ 

    protected void finalize() throws Throwable { 

    } 

PS:這里有一個技術(shù)交流群(扣扣群:1158819530),方便大家一起交流,持續(xù)學習,共同進步,有需要的可以加一下。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品国产91高清在线观看 | 法国老妇性xx在线播放 | 福利片免费一区二区三区 | 欧美一级片免费在线观看 | 欧美特级午夜一区二区三区 | 三级伦理影院 | 精品一区二区三区在线成人 | 欧美日韩国内 | 午夜国产在线观看 | 百合漫画咱啪全彩抚慰 | 亚洲老头与老太hd | 青青色在线观看 | 2022av小四郎的最新地址 | 毛片手机在线视频免费观看 | 欧美1区 | 亚洲精品国产一区二区在线 | 欧美人禽杂交在线视频 | 国产在线看片网站 | 亚洲一级视频在线观看 | 久久99热成人精品国产 | 日本天堂网| 日本午夜视频 | 99在线观看免费视频 | 午夜伦理电影在线观免费 | 日本人成年视频在线观看 | 99久久国产综合精品麻豆 | 亚洲精品国产专区91在线 | 日韩成人免费aa在线看 | 亚洲国产精品久久网午夜 | 免费人成在线观看 | 青青成人 | xxx中国bbbwww| 国产精品第一 | 无限韩国视频免费播放 | 高h文恩好大好爽 | 国产自拍专区 | 国产成人亚洲综合网站不卡 | 国产传媒在线播放 | 国产高清国内精品福利色噜噜 | 性xxxx欧美高清 | 女人张开腿让男人桶视频免费大全 |