摘要:注釋指出方法返回散列值。直到其他線程調用此對象的方法或方法,當前線程被喚醒進入就緒狀態。總超時時間以納秒為單位計算為。以上注釋主要就是描述了,和方法的使用規范。主要的區別在于在釋放同時,釋放了對象鎖的控制。
Java 是一門面向對象的語言,在 Java 里面一切都可以看作是一個對象,而 Java 里面所有的對象都默認繼承于 Object 類,所以狗哥今天就復習了一遍這個類。
上圖看出 Object 一共有 12 個方法,其中 registerNatives() 是由 C 語言實現的,這個不在研究范圍內。
1、getClass/** * Returns the runtime class of this {@code Object}. The returned * {@code Class} object is the object that is locked by {@code * static synchronized} methods of the represented class. */ public final native Class> getClass();
這個方法的作用就是返回某個對象的運行時類,它的返回值是 Class 類型,Class c = obj.getClass();通過對象 c ,我們可以獲取該對象的所有成員方法,每個成員方法都是一個 Method 對象;我們也可以獲取該對象的所有成員變量,每個成員變量都是一個 Field 對象;同樣的,我們也可以獲取該對象的構造函數,構造函數則是一個 Constructor 對象。這個方法在反射時會常用到。
2、hashCode/** * Returns a hash code value for the object. This method is * supported for the benefit of hash tables such as those provided by * {@link java.util.HashMap}. */ public native int hashCode();
這個方法的注釋比較長,就不放出來了。注釋指出:
hashCode 方法返回散列值。
返回值默認是由對象的地址轉換而來的。
同一個對象調用 hashCode 的返回值是相等的。
兩個對象的 equals 相等,那 hashCode 一定相等。
兩個對象的 equals 不相等,那 hashCode 也不一定相等。
3、equalspublic 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 ?
這個問題之前分享過舊文:https://mp.weixin.qq.com/s/iI...
4、cloneprotected native Object clone() throws CloneNotSupportedException;
clone() 是 Object 的 protected 方法,它不是 public,一個類不顯式去重寫 clone(),其它類就不能直接去調用該類實例的 clone() 方法。此外,Clone 的注釋中還提到比較重要的幾點:
克隆的對象必須要實現 Cloneable 接口并重寫 clone 方法,否則會報 CloneNotSupportedException 異常
clone() 方法并不是 Cloneable 接口的方法,而是 Object 的一個 protected 方法。Cloneable 接口只是規定,如果一個類沒有實現 Cloneable 接口又調用了 clone() 方法,就會拋出 CloneNotSupportedException。
淺拷貝:拷貝對象和原始對象的引用類型引用同一個對象。
深拷貝:拷貝對象和原始對象的引用類型引用不同對象。
關于淺拷貝與深拷貝的詳解,請看這篇舊文:
https://mp.weixin.qq.com/s/I6...
public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
這個方法應該沒什么好講的,原生的 toString 方法僅僅返回,對象名 + 它的 hashCode ,但做過開發的都知道,原生的 toString 作用不大。我們需要重寫 toString 一般是因為方便調試,需要知道對象的屬性值,而不僅僅是 hashCode 。所以,應該像下面這樣重寫:
public class Student { private int age; private String name; // 省略 get、set @Override public String toString() { return "Student{" + "age=" + age + ", name="" + name + """ + "}"; } }6、notify 和 wait
public final native void notify(); public final native void notifyAll();
首先是 notify ,注釋就不貼出來了,notify 的作用就是隨機喚醒在等待隊列的某個線程,而 notifyAll 就是喚醒在等待隊列的所有線程。
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 的作用是讓當前線程進入等待狀態,同時,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) 效果一樣。
除此之外,notify 和 wait 的注釋中還有這么一段:
** This method should only be called by a thread that is the owner * of this object"s monitor. A thread becomes the owner of the * object"s monitor in one of three ways: *
看到這英文,剛過四級的我瑟瑟發抖。以上注釋主要就是描述了,notify 和 wait 方法的使用規范。意思就是這二者必須在 synchronized 修飾的同步方法或同步代碼中使用。
為什么 wait() 必須在同步 (Synchronized) 方法/代碼塊中調用?
答:調用 wait() 就是釋放鎖,釋放鎖的前提是必須要先獲得鎖,先獲得鎖才能釋放鎖。
為什么 notify()、notifyAll() 必須在同步 (Synchronized) 方法/代碼塊中調用?
答:notify()、notifyAll() 是將鎖交給含有 wait() 方法的線程,讓其繼續執行下去,如果自身沒有鎖,怎么叫把鎖交給其他線程呢?(本質是讓處于入口隊列的線程競爭鎖)
詳細解釋請參考這篇博文:https://blog.csdn.net/qq_42145871/article/details/81950949
Thread.sleep() 和 Object.wait() 有什么區別?
首先,二者都可以暫停當前線程,釋放 CPU 控制權。主要的區別在于 Object.wait()在釋放 CPU 同時,釋放了對象鎖的控制。而 Thread.sleep() 沒有對鎖釋放。換句話說 sleep 就是耍流氓,占著茅坑不拉屎。
推薦閱讀:1、java | 什么是動態代理
2、SpringBoot?| 啟動原理
3、SpringBoot | 自動配置原理
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76021.html
摘要:對于如果以修改源碼的方式,也可以通過判斷當前的數據類型是否與預期的數據類型一致的方式進行。但由于每種數據類型都是一個匿名內部類,很難通過判斷預期的數據類型是啥,所以可以通過添加捕獲異常,在發生異常后,跳過解析。 一、項目地址 項目地址:github-gson-plugin 二、Gson解析核心類 1.ArrayTypeAdapter.JAVA 用于解析數組類型的數據 public ...
摘要:數組的大小會根據容量的增長而動態的增長,具體的增長方式請看這里構造函數提供了三種方式的構造器。這些元素按照該的迭代器返回的順序排列的。 原文地址 ArrayList ArrayList是List接口的 可變數組的實現。實現了所有可選列表操作,并允許包括 null 在內的所有元素。除了實現 List接口外,此類還提供一些方法來操作內部用來存儲列表的數組的大小。ArrayList繼承自 A...
摘要:在版本中,支持五種序列化方式,分別是依賴阿里的庫,功能強大支持普通類包括任意或完全兼容序列化協議的系列化框架,序列化速度大概是的倍,大小是大小的左右。但這里實際不是原生的序列化,而是阿里修改過的,它是默認啟用的序列化方式自帶的序列化實現。 序列化——開篇 目標:介紹dubbo中序列化的內容,對dubbo中支持的序列化方式做對比,介紹dubbo-serialization-api下的源碼...
摘要:時間年月日星期日說明本文部分內容均來自慕課網。慕課網教學示例源碼無個人學習源碼第一章課程概述課程介紹課程須知本課程面向所有使用語言進行開發的小伙伴。 時間:2017年05月21日星期日說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示例源碼:無個人學習源碼:https://github.com/zccodere/s... 第一章:課程概述 1-1 ...
閱讀 2169·2021-11-11 16:55
閱讀 1692·2019-08-30 15:54
閱讀 2822·2019-08-30 15:53
閱讀 2216·2019-08-30 15:44
閱讀 1156·2019-08-30 15:43
閱讀 970·2019-08-30 11:22
閱讀 1947·2019-08-29 17:20
閱讀 1572·2019-08-29 16:56