詳解Java中Object?類的使用
Java的Object 類是所有類的父類,也就是說 Java 的所有類都繼承了 Object,子類可以使用 Object 的所有方法。Object 類位于 java.lang 包中,編譯時會自動導(dǎo)入,我們創(chuàng)建一個類時,如果沒有明確繼承一個父類,那么它就會自動繼承 Object,成為 Object 的子類。

Object 類可以顯式繼承,也可以隱式繼承,以下兩種方式是一樣的:
// 顯式繼承:
public class Runoob extends Object{ }// 隱式繼承:
public class Runoob { }Object 類提供的方法
| 方法 | 描述 |
|---|---|
| Object() | 構(gòu)造一個新對象 |
| protected Object clone() | 創(chuàng)建并返回一個對象的拷貝 |
| boolean equals(Object obj) | 比較兩個對象是否相等 |
| protected void finalize() | 當(dāng) GC (垃圾回收器)確定不存在對該對象的有更多引用時,由對象的垃圾回收器調(diào)用此方法 |
| Class<?> getClass() | 獲取對象的運行時對象的類 |
| int hashCode() | 獲取對象的 hash 值 |
| void notify() | 喚醒在該對象上等待的某個線程 |
| void notifyAll() | 喚醒在該對象上等待的所有線程 |
| String toString() | 返回對象的字符串表示形式 |
| void wait() | 讓當(dāng)前線程進入等待狀態(tài)。直到其他線程調(diào)用此對象的 notify() 方法或 notifyAll() 方法 |
| void wait(long timeout) | 讓當(dāng)前線程處于等待(阻塞)狀態(tài),直到其他線程調(diào)用此對象的 notify() 方法或 notifyAll() 方法,或者超過參數(shù)設(shè)置的timeout超時時間 |
| void wait(long timeout, int nanos) | 與 wait(long timeout) 方法類似,多了一個 nanos 參數(shù),這個參數(shù)表示額外時間(以納秒為單位,范圍是 0-999999)。 所以超時的時間還需要加上 nanos 納秒 |
方法實例
clone() 方法
protected native Object clone() throws CloneNotSupportedException;
描述:
用于創(chuàng)建并返回一個對象的拷貝。clone 方法是淺拷貝,對象內(nèi)屬性引用的對象只會拷貝引用地址,而不會將引用的對象重新分配內(nèi)存。
參數(shù):
無
返回值:
返回一個對象的拷貝。
注意:
由于 Object 本身沒有實現(xiàn) Cloneable 接口,所以不重寫 clone 方法并且進行調(diào)用的話會發(fā)生 CloneNotSupportedException 異常。
public class Test implements Cloneable {
// 聲明變量
String name;
int likes;
// 屬性引用的對象
JueJin jueJin;
Test() {
this.jueJin = new JueJin();
}
public static void main(String args[]) {
// 創(chuàng)建對象
Test obj1 = new Test();
// 初始化變量
obj1.name = "Runoob";
obj1.likes = 111;
obj1.jueJin.name = "掘金";
// 打印輸出
System.out.println("obj1 的 name = " + obj1.name); // Runoob
System.out.println("obj1 的 likes = " + obj1.likes); // 111
System.out.println("obj1 的 jueJin 的 name = " + obj1.jueJin.name); //掘金
try {
// 創(chuàng)建 obj1 的拷貝
Test obj2 = (Test) obj1.clone();
obj2.name = "JueJin";
obj2.likes = 222;
obj2.jueJin.name = "稀土掘金";
// 使用 obj2 輸出變量
System.out.println();
System.out.println("obj2 的 name = " + obj2.name); // JueJin
System.out.println("obj2 的 likes = " + obj2.likes); // 222
System.out.println("obj2 的 jueJin 的 name = " + obj2.jueJin.name); //稀土掘金
System.out.println();
System.out.println("淺拷貝的問題");
System.out.println("obj1 的 name = " + obj1.name); // Runoob
System.out.println("obj1 的 likes = " + obj1.likes); // 111
System.out.println("obj1 的 jueJin 的 name = " + obj1.jueJin.name); //稀土掘金
} catch (Exception e) {
System.out.println(e);
}
}
}
class JueJin {
public String name;
}
// 以上程序執(zhí)行結(jié)果為:
// obj1 的 name = Runoob
// obj1 的 likes = 111
// obj1 的 jueJin 的 name = 掘金
// obj2 的 name = JueJin
// obj2 的 likes = 222
// obj2 的 jueJin 的 name = 稀土掘金
// 淺拷貝的問題
// obj1 的 name = Runoob
// obj1 的 likes = 111
// obj1 的 jueJin 的 name = 稀土掘金解析:
由于淺拷貝對對象內(nèi)屬性引用的對象只會拷貝引用地址,所以 obj1 與 obj2 的 jueJin 屬性引用的對象指向同一內(nèi)存地址,所以在 obj2 修改 jueJin 的 name 屬性后,obj1 的 jueJin 的 name 屬性也發(fā)生了變化。
equals() 方法
public boolean equals(Object obj)
描述:
用于比較兩個對象是否相等。比較兩個對象時,是通過判斷兩個對象引用指向的是同一個對象,即比較 2 個對象的內(nèi)存地址是否相等。
參數(shù):
obj -- 要比較的對象。
返回值:
如果兩個對象相等返回 true,否則返回 false。
注意:
不同的類重寫了 equals() 方法,導(dǎo)致equals() 方法的行為有所不同。但如果子類重寫了 equals() 方法,就需要重寫 hashCode() 方法,比如 String 類就重寫了 equals() 方法,同時也重寫了 hashCode() 方法。
public class Test implements Cloneable {
public static void main(String args[]) {
// 創(chuàng)建兩個對象
Object obj1 = new Object();
Object obj2 = new Object();
// 判斷 obj1 與 obj2 是否相等
// 不同對象,內(nèi)存地址不同,不相等,返回 false
System.out.println(obj1.equals(obj2)); // false
// obj1 賦值給 obj3
// 對象引用,內(nèi)存地址相同,相等,返回 true
Object obj3 = obj1;
System.out.println(obj1.equals(obj3)); // true
}
}
// 以上程序執(zhí)行結(jié)果為:
// false
// truefinalize() 方法
protected void finalize() throws Throwable { }描述:
用于實例被垃圾回收器回收的時觸發(fā)的操作。當(dāng) GC (垃圾回收器) 確定不存在對該對象的有更多引用時,對象的垃圾回收器就會調(diào)用這個方法。
參數(shù):
無
返回值:
無
public class Test {
public static void main(String args[]) {
JunJin junJin = new JunJin();
junJin = null;
System.gc();
}
}
class JunJin {
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("對象被回收了");
}
}
// 以上程序執(zhí)行結(jié)果為:
// 對象被回收了getClass() 方法
public final native Class<?> getClass();
描述:
用于獲取對象的運行時對象的類。
參數(shù):
無
返回值:
返回對象的類。
public class Test {
public static void main(String args[]) {
// getClass() with Object
Object obj1 = new Object();
System.out.println("obj1 的類為: " + obj1.getClass());
// getClass() with String
String obj2 = new String();
System.out.println("obj2 的類為: " + obj2.getClass());
// getClass() with ArrayList
ArrayList<Integer> obj3 = new ArrayList<>();
System.out.println("obj3 的類為: " + obj3.getClass());
}
}
// 以上程序執(zhí)行結(jié)果為:
// obj1 的類為: class java.lang.Object
// obj2 的類為: class java.lang.String
// obj3 的類為: class java.util.ArrayListhashCode() 方法
public native int hashCode();
描述:
用于獲取對象的 hash 值。
參數(shù):
無
返回值:
返回對象哈希值,是一個整數(shù),表示在哈希表中的位置。
public class Test {
public static void main(String args[]) {
// Object 使用 hashCode()
Object obj1 = new Object();
// obj1 賦值給 obj2
Object obj2 = obj1;
// 判斷兩個對象是否相等
System.out.println(obj1.equals(obj2)); // true
// 獲取 obj1 與 obj2 的哈希值
System.out.println("對象相等則hashCode一定相等");
System.out.println(obj1.hashCode()); // 225534817
System.out.println(obj2.hashCode()); // 225534817
}
}
// 以上程序執(zhí)行結(jié)果為:
// true
// 對象相等則hashCode一定相等
// 692404036
// 692404036wait() 方法
// 該方法有以下幾種語法格式: public final void wait() throws InterruptedException public final native void wait(long timeout) throws InterruptedException public final void wait(long timeout, int nanos) throws InterruptedException
描述:
讓當(dāng)前線程進入等待狀態(tài)。
參數(shù):
- timeout -- 等待超時時間(以毫秒為單位)。如果 timeout 參數(shù)為 0,則不會超時,會一直進行等待,類似于 wait() 方法。如果阻塞的時間超過該參數(shù)時間,會喚醒線程。
- nanos -- 額外時間(以納秒為單位,范圍是 0-999999)。如果設(shè)置該時間,超時的時間還需要加上 nanos 納秒。
返回值:
無
注意:
- 當(dāng)前線程必須是此對象的監(jiān)視器所有者,否則還是會發(fā)生 IllegalMonitorStateException 異常。
- 如果當(dāng)前線程在等待之前或在等待時被任何線程中斷,則會拋出 InterruptedException 異常。
- 如果傳遞的參數(shù)不合法,則會拋出 IllegalArgumentException 異常。
notify() 與 notifyAll() 方法
public final native void notify();
描述:
用于喚醒一個在此對象監(jiān)視器上等待的線程。如果所有的線程都在此對象上等待,那么只會選擇一個線程,選擇是任意性的,并在對實現(xiàn)做出決定時發(fā)生。
參數(shù):
無
返回值:
無
public final native void notifyAll();
描述:
用于喚醒在該對象上等待的所有線程。notifyAll() 方法跟 notify() 方法的區(qū)別在于 notifyAll() 方法喚醒在此對象監(jiān)視器上等待的所有線程,notify() 方法是一個線程。
參數(shù):
無
返回值:
無
public class Test {
// 聲明一個同步列表
private List synchedList;
/**
* 構(gòu)造方法
*/
public Test() {
// 創(chuàng)建一個同步列表
synchedList = Collections.synchronizedList(new LinkedList());
}
/**
* 刪除列表中的元素
* @return 刪除的元素
* @throws InterruptedException
*/
public String removeElement() throws InterruptedException {
synchronized (synchedList) {
// 列表為空就等待
while (synchedList.isEmpty()) {
System.out.println("列表是空的...");
System.out.println("線程 " + Thread.currentThread().getName() + " 將開始等待...");
synchedList.wait();
System.out.println("線程 " + Thread.currentThread().getName() + " 等待結(jié)束!");
}
// 刪除元素
String element = (String) synchedList.remove(0);
// 返回刪除的元素
return element;
}
}
/**
* 添加元素到列表
* @param element 要添加的元素
*/
public void addElement(String element) {
synchronized (synchedList) {
// 添加一個元素,并通知元素已存在
synchedList.add(element);
System.out.println("添加了新元素:'" + element + "'");
synchedList.notify();
System.out.println("notify 已調(diào)用,喚醒 synchedList 上等待的任意一個線程!");
//synchedList.notifyAll();
//System.out.println("notifyAll 已調(diào)用,喚醒 synchedList 上等待的所有線程!");
}
System.out.println("添加元素完成...");
}
/**
* main 函數(shù)
* @param args
*/
public static void main(String args[]) {
final Test demo = new Test();
Runnable runA = new Runnable() {
public void run() {
try {
// 刪除 synchedList 中的一個元素并輸出
String item = demo.removeElement();
System.out.println("刪除了元素 " + item);
} catch (InterruptedException ix) {
System.out.println("中斷的異常!");
} catch (Exception x) {
System.out.println("Exception thrown.");
}
}
};
Runnable runB = new Runnable() {
// 執(zhí)行添加元素操作,并開始循環(huán)
public void run() {
demo.addElement("Hello!");
}
};
try {
// 創(chuàng)建線程 threadA1 并開始執(zhí)行
Thread threadA1 = new Thread(runA, "Google");
threadA1.start();
// 當(dāng)前執(zhí)行 main 方法的線程休眠
Thread.sleep(500);
// 創(chuàng)建線程 threadA2 并開始執(zhí)行
Thread threadA2 = new Thread(runA, "Runoob");
threadA2.start();
// 當(dāng)前執(zhí)行 main 方法的線程休眠
Thread.sleep(500);
// 創(chuàng)建線程 threadB 并開始執(zhí)行
Thread threadB = new Thread(runB, "Taobao");
threadB.start();
// 當(dāng)前執(zhí)行 main 方法的線程休眠
Thread.sleep(1000);
// 中斷 threadA1 線程
threadA1.interrupt();
// 中斷 threadA2 線程
threadA2.interrupt();
} catch (InterruptedException x) {
System.out.println(x);
}
}
}使用 notify() 方法喚醒線程時,可以看到 Google 線程的等待被喚醒了,但 Runoob 線程的等待最終沒有被喚醒,輸出如下:
列表是空的...
線程 Google 將開始等待...
列表是空的...
線程 Runoob 將開始等待...
添加了新元素:'Hello!'
notify 已調(diào)用,喚醒 synchedList 上等待的任意一個線程!
添加元素完成...
線程 Google 等待結(jié)束!
刪除了元素 Hello!
中斷的異常!
使用 notifyAll() 方法喚醒線程時,可以看到 Runoob 與 Google 線程的等待都被喚醒了,但 Runoob 線程喚醒后將集合中的元素刪除了,所以集合再次變?yōu)榭盏模珿oogle 就再次進入了等待狀態(tài),輸出如下:
列表是空的...
線程 Google 將開始等待...
列表是空的...
線程 Runoob 將開始等待...
添加了新元素:'Hello!'
notifyAll 已調(diào)用,喚醒 synchedList 上等待的所有線程!
添加元素完成...
線程 Runoob 等待結(jié)束!
刪除了元素 Hello!
線程 Google 等待結(jié)束!
列表是空的...
線程 Google 將開始等待...
中斷的異常!
注意:
notify() 與 notifyAll() 方法只能被作為此對象監(jiān)視器的所有者的線程來調(diào)用。如果當(dāng)前線程不是此對象監(jiān)視器的所有者的話會拋出 IllegalMonitorStateException 異常。
一次只能有一個線程擁有對象的監(jiān)視器。一個線程要想成為對象監(jiān)視器的所有者,可以使用以下 3 種方法:
- 執(zhí)行對象的同步實例方法
- 使用 synchronized 內(nèi)置鎖
- 對于 Class 類型的對象,執(zhí)行同步靜態(tài)方法
toString() 方法
public String toString()
描述:
用于返回對象的字符串表示形式。
參數(shù):
無
返回值:
返回對象的字符串表示形式。默認(rèn)返回格式:對象的 class 名稱 + @ + hashCode 的十六進制字符串。
public class Test {
public static void main(String[] args) {
// toString() with Object
Object obj1 = new Object();
System.out.println(obj1.toString());
Object obj2 = new Object();
System.out.println(obj2.toString());
Object obj3 = new Object();
System.out.println(obj3.toString());
}
}
// 以上程序執(zhí)行結(jié)果為:
// java.lang.Object@29453f44
// java.lang.Object@5cad8086
// java.lang.Object@6e0be858以上就是詳解Java中Object 類的使用的詳細(xì)內(nèi)容,更多關(guān)于Java Object 類的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java中g(shù)et()方法和set()方法的作用淺析
這篇文章主要給大家介紹了關(guān)于java中g(shù)et()方法和set()方法的作用,set是是對數(shù)據(jù)進行設(shè)置,而get是對數(shù)據(jù)進行獲取,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07
Zuul 實現(xiàn)網(wǎng)關(guān)轉(zhuǎn)發(fā)的五種方式小結(jié)
這篇文章主要介紹了Zuul 實現(xiàn)網(wǎng)關(guān)轉(zhuǎn)發(fā)的五種方式小結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
Java對象池pool2分析PooledObjectFactory過程
文章介紹了Java中對象池化技術(shù)的背景,以Apache的Pool2庫為例,詳細(xì)講解了GenericObjectPool的構(gòu)造函數(shù)參數(shù)和PooledObjectFactory接口的實現(xiàn),通過商場里的共享充電寶的比喻,說明了池化思維的應(yīng)用2025-02-02

