1.Object是所有類的父類,任何類都默認繼承Object,即直接或間接的繼承java.lang.Object類。由於所有的類都繼承在Object類,因此省略了
extends Object關鍵字。
2.Object類中主要有以下方法:
toString() getClass() equals() clone() finalize() notify() notifyAll() wait()
其中toString(),getClass(),equals()是其中最重要的方法。getClass(),notify(),notifyAll(),wait()等方法被定義為final類型,因此不能重寫。
3.clone()方法
public class Object { protected native Object clone() throws CloneNotSupportedException; }
(1) clone()存在的原因是Java里除了8種基本類型傳參數是值傳遞,其他的類對象傳參數都是引用傳遞。可以在類中復寫clone方法以實現深拷貝。
(2) Object類的 clone() 方法是一個native方法,native方法的效率一般來說都是遠高於Java中的非native方法。這也解釋了為什么要用Object中clone()
方法而不是先new一個類,然后把原始對象中的信息復制到新對象中。
(3) 必須要重寫clone()方法以達到在類外使用的目的。
(4) Object.clone()方法返回一個Object對象, 必須進行強制類型轉換才能得到我們需要的類型。
在派生類中實現Cloneable接口。奇怪的發現Cloneable竟然是空的,它僅僅是一個標志,而且這個標志也僅僅是針對 Object類中 clone()方法的,如果 clone 類沒有實現
Cloneable 接口,並調用了 Object 的 clone() 方法(也就是調用了 super.Clone() 方法),那么Object 的 clone() 方法就會拋出
CloneNotSupportedException 異常。
clone使用demo1:

class Person implements Cloneable { //clone()是Object類中的protected成員方法。繼承Cloneable只是為了運行時不要報異常。 private int age ; private String name; public Person(int age, String name) { this.age = age; this.name = name; } public Person() {} public int getAge() { return age; } public String getName() { return name; } /* * 這里必須要復寫Object類的clone()方法,原因: * Object類中的clone()方法是protected權限,只能在本包中或者在其它包的子類中訪問(注意是子類中) * 這里重寫一下,雖然還是protected的,但是可以在本包中訪問了。 */ @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class Test { public static void main(String args[]) { Person p = new Person(23, "zhang"); Person p1 = null; try { p1 = (Person) p.clone(); //非子類中訪問clone()方法 } catch (CloneNotSupportedException e) { e.printStackTrace(); } if (p1 != null) { System.out.println(p); //若引用的是同一個類,打印的hash值是一樣的,clone的是不同的 System.out.println(p1); } } }
如果想要拷貝一個對象,這個對象必須要實現Cloneable接口,實現clone方法。
clone使用demo2:

public class CloneTest { static class Body implements Cloneable { /**/ public Head head; public Body() {} public Body(Head head) { this.head = head; } @Override protected Object clone() throws CloneNotSupportedException { Body newBody = (Body)super.clone(); newBody.head = (Head)head.clone(); // return newBody; } } static class Head implements Cloneable { public Face face; public Head() {} public Head(Face face){ this.face = face; } @Override protected Object clone() throws CloneNotSupportedException { Head newHead = (Head)super.clone(); newHead.face = (Face)face.clone(); // face.clone();相對於Face類來說在Face類外部,若Face類沒有重寫這個接口將報錯 return newHead; } } static class Face implements Cloneable { @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public static void main(String[] args) throws CloneNotSupportedException { Body body = new Body(new Head(new Face())); Body body1 = (Body) body.clone(); System.out.println("body == body1 : " + (body == body1) ); System.out.println("body.head == body1.head : " + (body.head == body1.head)); System.out.println("body.head.face == body1.head.face : " + (body.head.face == body1.head.face)); } }
若Face類不實現Cloneable接口,Head類中也不調用face.clone(),那么成員對象face傳的還是引用!這就是一種不徹底的深拷貝。
結論:如果想要深拷貝一個對象,這個對象必須要實現Cloneable接口,實現clone方法,並且在clone方法內部,把該對象成員變量中引用的其他對象也要clone一份,這就要求這個被成員對象引用的對象必須也要實現Cloneable接口並且重寫clone方法。
4.toString()方法
public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
一般子類重寫這個方法以便打印自己想到的內容。
5.getClass()方法
public final native Class<?> getClass();
返回此Object運行時類類型,final修飾不可重寫,一般和getName()聯合使用,如getName().getClass().
6.finalize()方法
protected void finalize() throws Throwable {}
該方法用於釋放資源。因為無法確定該方法什么時候被調用,很少使用。
關於垃圾回收,有三點需要記住:
a.對象可能不被垃圾回收,只要程序沒有瀕臨存儲空間用完的那一刻,對象占用的空間就總也得不到釋放。
b.垃圾回收並不等於“析構”。
c.垃圾回收只與內存有關,使用垃圾回收的唯一原因是為了回收程序不再使用的內存。
7.equals()方法
public boolean equals(Object obj) { return (this == obj); }
直接判斷的是引用,若想判斷內容是否相同,需要重寫此方法。
8.hashCode()方法
public native int hashCode();
返回該對象的哈希值,該方法用於哈希查找.
9.wait()方法
public final native void wait() throws InterruptedException; public final native void wait(long timeout) throws InterruptedException; //超時時間timeout ms
wait()方法一直等待,直到獲得鎖或者被中斷。wait(timeout)如果在規定時間內沒有獲得鎖就返回。
調用該方法后當前線程進入睡眠狀態,直到以下事件發生。
a.其他線程調用了該對象的notify方法。
b.其他線程調用了該對象的notifyAll方法。
c.其他線程調用了interrupt中斷該線程。
d.時間間隔到了。
注意:只有獲取鎖后wait()方法才起作用,沒有獲取鎖調用wiat()方法無效。調用wait()方法后會釋放線程鎖,等待結束后重新獲取鎖繼續執行。

class A { public synchronized void printThreadInfo() throws InterruptedException { int i = 0; while (i++ < 5) { this.wait(1000); System.out.println("Still need wait resourse"); } } } public class Test { public static void main(String args[]) { A a = new A(); try { a.printThreadInfo(); } catch (InterruptedException e) { e.printStackTrace(); } } }

public class WaitNotifyTest { public static void main(String[] args) { final Object lock = new Object(); //局部變量lock在內部類中訪問了,需要加上final修飾 new Thread(new Runnable() { @Override public void run() { System.out.println("線程A等待獲取lock鎖"); synchronized (lock) { try { System.out.println("線程A獲取了lock鎖"); Thread.sleep(1000); System.out.println("線程A將要運行lock.wait()方法進行等待"); lock.wait(); System.out.println("線程A等待結束"); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println("線程B等待獲取lock鎖"); synchronized (lock) { System.out.println("線程B獲取了lock鎖"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程B將要運行lock.notify()方法進行通知"); lock.notify(); } } }).start(); } }
JVM的一些函數使用了JNI
static JNINativeMethod methods[] = { {"hashCode", "()I", (void *)&JVM_IHashCode}, {"wait", "(J)V", (void *)&JVM_MonitorWait}, {"notify", "()V", (void *)&JVM_MonitorNotify}, {"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll}, {"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone}, };
參考:https://blog.csdn.net/qq_38293564/article/details/80432875
10.notify()方法
public final native void notify();
該方法喚醒在該對象上等待的某個線程。
11.notifyAll()方法
public final native void notifyAll();
該方法喚醒在該對象上等待的所有線程。