中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java基礎之如何理解Object源碼

發布時間:2021-10-23 11:42:48 來源:億速云 閱讀:115 作者:iii 欄目:編程語言

本篇內容主要講解“Java基礎之如何理解Object源碼”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java基礎之如何理解Object源碼”吧!

getClass

public final native Class getClass();

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

hashCode

public native int hashCode();
  • hashCode 方法返回散列值。

  • 返回值默認是由對象的地址轉換而來的。

  • 同一個對象調用 hashCode 的返回值是相等的。

  • 兩個對象的 equals 相等,那 hashCode 一定相等。

  • 兩個對象的 equals 不相等,那 hashCode 也不一定相等。

equals

public boolean equals(Object obj) {     return (this == obj); }

equals 的實現非常簡單,它的作用就是比較兩個對象是否相等,而比較的依據就是二者的內存地址。除此之外,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、一致性,只要對象沒有被修改,多次調用 equals() 方法結果不變: x.equals(y) == x.equals(y); // true  5、非空性,對任何不是 null 的對象 x 調用 x.equals(null) 結果都為 false : x.equals(null); // false;

為什么要重寫 hashcode 和 equals ?

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

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

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

clone

protected native Object clone() throws CloneNotSupportedException;

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

  • 克隆的對象必須要實現 Cloneable 接口并重寫 clone 方法,否則會報 CloneNotSupportedException 異常

  • clone() 方法并不是 Cloneable 接口的方法,而是 Object 的一個 protected 方法。Cloneable  接口只是規定,如果一個類沒有實現 Cloneable 接口又調用了 clone() 方法,就會拋出  CloneNotSupportedException。

  • 淺拷貝:拷貝對象和原始對象的引用類型引用同一個對象。

  • 深拷貝:拷貝對象和原始對象的引用類型引用不同對象。

關于淺拷貝與深拷貝我們后面再討論。

toString

public String toString() {  return getClass().getName() + "@" + Integer.toHexString(hashCode()); }

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

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

  • Integer.toHexString(hashCode()); 將哈希值轉成16進制數格式的字符串。

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 的作用是讓當前線程進入等待狀態,同時,wait() 也會讓當前線程釋放它所持有的鎖。直到其他線程調用此對象的 notify() 方法或  notifyAll() 方法,當前線程被喚醒進入就緒狀態。

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

wait(long timeout, int nanos) 和 wait(long timeout)  功能一樣,唯一的區別是這個可以提供更高的精度。總超時時間(以納秒為單位)計算為 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 方法的使用規范。意思就是這二者必須在 synchronized 修飾的同步方法或同步代碼中使用。

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

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

完整代碼

package java.lang;   public class Object {      /**      * 一個本地方法,具體是用C(C++)在DLL中實現的,然后通過JNI調用      */     private static native void registerNatives();      /**      * 對象初始化時自動調用此方法      */     static {         registerNatives();     }      /**      * 返回此Object的運行時類      */     public final native Class<?> getClass();      /**      * hashCode的常規協定是:      * 1.在java應用程序執行期間,在對同一對象多次調用hashCode()方法時,必須一致地返回相同的整數,前提是將對象進行equals比較時所用的信息沒有被修改。      * 從某一應用程序的一次執行到同一應用程序的另一次執行,該整數無需保持一致。      * 2.如果根據equals(object)方法,兩個對象是相等的,那么對這兩個對象中的每個對象調用hashCode方法都必須生成相同的整數結果。      * 3.如果根據equals(java.lang.Object)方法,兩個對象不相等,那么對這兩個對象中的任一對象上調用hashCode()方法不要求一定生成不同的整數結果。      * 但是,程序員應該意識到,為不相等的對象生成不同整數結果可以提高哈希表的性能。      */     public native int hashCode();      /**      * 這里比較的是對象的內存地址      */     public boolean equals(Object obj) {         return (this == obj);     }      /**      * 本地clone方法,用于對象的復制      */     protected native Object clone() throws CloneNotSupportedException;      /**      * 返回該對象的字符串表示,非常重要的方法      * getClass().getName();獲取字節碼文件的對應全路徑名例如java.lang.Object      * Integer.toHexString(hashCode());將哈希值轉成16進制數格式的字符串。      */     public String toString() {         return getClass().getName() + "@" + Integer.toHexString(hashCode());     }      /**      * 不能被重寫,用于喚醒一個在因等待該對象(調用了wait方法)被處于等待狀態(waiting 或 time_wait)的線程,該方法只能同步方法或同步塊中調用      */     public final native void notify();      /**      * 不能被重寫,用于喚醒所有在因等待該對象(調用wait方法)被處于等待狀態(waiting或time_waiting)的線程,該方法只能同步方法或同步塊中調用      */     public final native void notifyAll();      /**      * 不能被重寫,用于在線程調用中,導致當前線程進入等待狀態(time_waiting),timeout單位為毫秒,該方法只能同步方法或同步塊中調用,超過設置時間后線程重新進入可運行狀態      */     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);     }      /**      * 在其他線程調用此對象的notify()方法或notifyAll()方法前,導致當前線程等待。換句話說,此方法的行為就好像它僅執行wait(0)調用一樣。      * 當前線程必須擁有此對象監視器。      * 該線程發布對此監視器的所有權并等待,直到其他線程通過調用notify方法或notifyAll方法通知在此對象的監視器上等待的線程醒來,      * 然后該線程將等到重新獲得對監視器的所有權后才能繼續執行。      */     public final void wait() throws InterruptedException {         wait(0);     }      /**      * 這個方法用于當對象被回收時調用,這個由JVM支持,Object的finalize方法默認是什么都沒有做,如果子類需要在對象被回收時執行一些邏輯處理,則可以重寫finalize方法。      */     protected void finalize() throws Throwable {     } }

到此,相信大家對“Java基礎之如何理解Object源碼”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

石台县| 左贡县| 兴城市| 岳阳市| 新宁县| 邓州市| 吐鲁番市| 义乌市| 巨鹿县| 安康市| 杨浦区| 兴海县| 怀来县| 祁阳县| 紫云| 饶阳县| 安吉县| 绵阳市| 通道| 巴楚县| 南和县| 车致| 台北县| 土默特左旗| 藁城市| 黄陵县| 雅安市| 龙山县| 大丰市| 芜湖县| 高台县| 龙门县| 开原市| 花莲市| 金华市| 镇巴县| 九江县| 昆明市| 丹东市| 壤塘县| 买车|