JDK版本: 1.8java
最近想看看jdk源碼提升下技術深度(比較閒),萬物皆對象,雖然Object大多native方法但仍是很重要的。app
package java.lang; /** * Java中的始祖,萬物皆Object * @since JDK1.0 */ public class Object { private static native void registerNatives(); static { // 保證在clinit()最早執行,從而調native方法 registerNatives(); } /** * 返回運行時的Class類文件,返回的是個泛型,運行時泛型會進行類型擦除,實際返回以自身爲邊界 * 例如 new HelloWorld().getClass() * 返回 Class<? extends HelloWorld> */ public final native Class<?> getClass(); /** * 返回一個hash code整數,主要用於集合類使用,例如HashMap * 屢次調用返回值必須同樣,可是同一個應用執行了多份的時候,不保證多個執行中值相等 * 若是兩個對象調equels方法返回ture,那麼hash code值必定相等(因此重寫equels方法必定要重寫hashCode方法) * 若是兩個對象調equels方法返回false,hash code值不必定不相等,可是咱們重寫hashCode方法時,應該儘可能作到不等,從而減小hash碰撞 * 不一樣虛擬機的實現不太同樣,可是主要是根據對象的內存地址來計算的 */ public native int hashCode(); /** * 對於非空的對象進行邏輯上是否相等的比較,默認是比較的內存地址 * 再次強調哈哈,若是兩個對象調equels方法返回ture,那麼hash code值必定相等(因此重寫equels方法必定要重寫hashCode方法) * 四大特性(1)reflexive自反性(2)symmetric對稱性(3)transitive傳遞性(4)consistent一致性 */ public boolean equals(Object obj) { return (this == obj); } /** * 返回一個當前對象的副本,通常須要知足以下性質: * x.clone() != x * x.clone().getClass() == x.getClass() * x.clone().equals(x) * 能夠根據須要實現淺拷貝和深拷貝,通常是淺拷貝 * @throws CloneNotSupportedException Object沒有實現Cloneable接口,自己是不能使用clone方法的,其子類調用clone方法會拋出此異常.只有實現了Cloneable才能正常使用 * @see java.lang.Cloneable */ protected native Object clone() throws CloneNotSupportedException; /** * 返回一個對象的字符串表示 * 建議全部類都重寫這個方法,由於不直觀 * 字符串內容,類名加上hash code轉成16進制 */ public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } /** * 用於隨機喚醒一個在對象等待池中的線程 * 被喚醒的線程不會馬上拿到對象的監視器鎖,而是和其餘在線程共同競爭,拿到鎖以後恢復到調用wait方法時的同步狀態 * 同一時間只有一個線程能拿到監視器鎖 * * @throws IllegalMonitorStateException 若是當前執行notify方法的線程沒拿到對象的監視器鎖 */ public final native void notify(); /** * 一次喚醒全部等待池中的線程,其餘和notify方法同樣 */ public final native void notifyAll(); /** * 持有對象監視器的線程能夠執行awit方法把本身放入等待池中,而且放棄持有該對象的全部同步資源,不會放棄獲取的其餘對象的同步資源 * 有四種狀況線程能夠逃出等待池: * 其餘線程調用notify方法 * 其餘線程調用notifyAll方法 * 其餘線程調用interrupts方法 * 超時時間到了 * 逃出等待池拿到鎖以後恢復到調用wait方法時的同步狀態 * 特別強調,若是由於interrupts逃出了等待池,不會馬上拋出InterruptedException,須要等到線程拿到鎖 * 因爲偶爾會發生僞喚醒(沒有調用notify或interrupts也沒超時),因此咱們在編碼時應該以下例: * synchronized (obj) { * while (<condition does not hold>) * obj.wait(timeout); * ... // Perform action appropriate to condition * } * @param timeout 在等待池中的最長等待時間,時間到了就出獄了,若是值爲0,則無期徒刑等待保釋 * @throws IllegalArgumentException 超時時間是負數 * @throws IllegalMonitorStateException 當前線程沒有拿到監視器鎖 * @throws InterruptedException 中斷位爲true */ public final native void wait(long timeout) throws InterruptedException; /** * 提供納秒級別的等待控制,其餘同wait(long timeout) * @param nanos 額外的納秒時間 * 0-999999. * @throws IllegalArgumentException timeout是負數,nanos是負數或者大於999999. */ 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(long timeout)方法同樣,只是沒有超時時間 */ public final void wait() throws InterruptedException { wait(0); } /** * 當垃圾收集器判斷此對象沒有被任何引用,是垃圾對象了,由垃圾收集器執行此方法銷燬對象,因此什麼時候執行是不肯定的 * JVM保證垃圾收集器調用此方法時候,該對象的鎖不被任何線程持有了 * finalize方法只會被執行一次,因此咱們能夠重寫此方法特定一些清除工做,或者給對象一次復活機會,可是不建議重寫此方法 * @throws Throwable the {@code Exception} raised by this method * @see java.lang.ref.WeakReference * @see java.lang.ref.PhantomReference */ protected void finalize() throws Throwable { } }
public class ObjectCloneTest { /** * 不實現 Cloneable 接口 * * 輸出: * Exception in thread "main" java.lang.CloneNotSupportedException: study.ObjectCloneTest$Obj * at java.lang.Object.clone(Native Method) * at study.ObjectCloneTest$Obj.main(ObjectCloneTest.java:24) */ private static class Obj { public static void main(String[] args) throws CloneNotSupportedException { Obj o1 = new Obj(); Object o2 = o1.clone(); } } /** * 實現 Cloneable 接口,從結果看出默認實現是淺拷貝 * * 輸出: * 兩個對象地址相同麼 * false * 兩個對象的屬性地址相同麼 * true * 改變其中一個屬性會變麼? * [1, 2] * [1, 2] */ private static class ObjShallowCopy implements Cloneable { private List<String> list = new ArrayList<>(); @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } public static void main(String[] args) throws CloneNotSupportedException { ObjShallowCopy o1 = new ObjShallowCopy(); o1.list.add("1"); ObjShallowCopy o2 = (ObjShallowCopy) o1.clone(); System.out.println("兩個對象地址相同麼"); System.out.println(o1 == o2); System.out.println("兩個對象的屬性地址相同麼"); System.out.println(o1.list == o2.list); System.out.println("改變其中一個屬性會變麼?"); o2.list.add("2"); System.out.println(o1.list.toString()); System.out.println(o2.list.toString()); } } /** * 實現 Cloneable 接口,比較笨拙的作了一層深拷貝,只爲了演示,深拷貝也能夠經過序列號等方式實現 * * 輸出: * 兩個對象地址相同麼 * false * 兩個對象的屬性地址相同麼 * false * 改變其中一個屬性會變麼? * [1] * [1, 2] */ private static class ObjDeepCopy implements Cloneable { private List<String> list = new ArrayList<>(); @Override protected Object clone() throws CloneNotSupportedException { ObjDeepCopy obj = (ObjDeepCopy) super.clone(); List<String> list = new ArrayList<>(obj.list.size()); list.addAll(obj.list); obj.list = list; return obj; } public static void main(String[] args) throws CloneNotSupportedException { ObjDeepCopy o1 = new ObjDeepCopy(); o1.list.add("1"); ObjDeepCopy o2 = (ObjDeepCopy) o1.clone(); System.out.println("兩個對象地址相同麼"); System.out.println(o1 == o2); System.out.println("兩個對象的屬性地址相同麼"); System.out.println(o1.list == o2.list); System.out.println("改變其中一個屬性會變麼?"); o2.list.add("2"); System.out.println(o1.list.toString()); System.out.println(o2.list.toString()); } } }
public class ObjectWaitNotifyTest { private volatile boolean flag = true; public static void main(String[] args) { ObjectWaitNotifyTest obj = new ObjectWaitNotifyTest(); new Thread(() -> { synchronized (obj) { System.out.println("絕食!"); while (obj.flag == true) { try { obj.wait(); System.out.println("真香!"); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); new Thread(() -> { synchronized (obj) { obj.flag = false; obj.notify(); System.out.println("海底撈走起!"); } }).start(); /** * 輸出: * 絕食! * 海底撈走起! * 真香! */ } }