Object類中的方法詳解

Object中的方法

Clone方法

protected Object clone() throws CloneNotSupportedException

創建並返回此對象的一個副本。

修飾符爲protected,保證了只有在該類 同一個包下 以及子類可以訪問。但是如果子類和基類不在同一個包下,子類在進行訪問的時候,只能訪問自身從基類繼承過來的protected方法,不能訪問基類實例中受保護的clone方法。如果子類和基類在同一個包下,那麼protected就相當於public。

原來對象修改某些屬性後,clone之後的新對象的屬性並不會發生變化。(如果屬性值是一個引用,這就例外了,因爲都指向同一塊內存區域,這就是淺表複製。如果是深表複製,那麼在拷貝的時候會把引用所指向的那個對象也拷貝過來,不是拷貝那個引用本身了,這樣就可以做到原有對象和拷貝之後的新對象完全獨立,一方的改變不會影響另外一方)。
Clone之後的對象和之前的對象的類型是一樣的(getClass).

淺表拷貝:
在對某個對象拷進行clone時,對其是一無所知的,僅僅是簡單的執行對屬性的copy。
這裏寫圖片描述
上述的拷貝過程,由於屬性hireDay是一個引用(對象),那麼在拷貝的時候只會把這個引用拷貝過來,新的對象和原來的對象都指向Date這塊內存了。
那麼如何實現深表拷貝呢?一種方法是通過對那些非基本數據類型的屬性進行特殊的處理,重新定義clone方法。如下:

Class Employee implements Cloneable {
    public object clone() throws CloneNotSupportedException {
        Emploee clonedEmploee = (Employee)super.clone();
        clonedEmploee.hireDay = (Date)hireDay.clone();
        return clonedEmploee;
} 
}

另外一種方法就是通過序列化,轉換爲流的方式進行讀寫。
這裏寫圖片描述
在使用的時候要注意是使用淺表拷貝還是深表拷貝。
調用clone方法的對象所屬的類必須實現Cloneable接口,重寫clone方法,並設置訪問修飾符爲public,方法中調用super.clone()方法得到需要複製的對象。

equals方法

boolean equals(Object obj)
指示某個其他對象是否與此對象“相等”
==運算符判斷兩個引用是否指向同一個對象。
Object類中的equal方法:

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

判斷調用equals方法的引用和傳進來的引用是否一致,也就是是否指向同一個對象。

特點
自反性(reflexive):任何非空引用x,x.equals(x)返回爲true。
對稱性(symmetric):任何非空引用x和y,x.equals(y)返回true當且僅當y.equals(x)返回true。
  傳遞性(transitive):任何非空引用x和y,如果x.equals(y)返回true,並且y.equals(z)返回true,那麼x.equals(z)返回true。
  一致性(consistent):兩個非空引用x和y,x.equals(y)的多次調用應該保持一致的結果,(前提條件是在多次比較之間沒有修改x和y用於比較的相關信息)。
  約定:對於任何非空引用x,x.equals(null)應該返回爲false。
  並且覆寫equals()方法時,應該同時覆寫hashCode()方法,反之亦然。(滿足hashcode的常規協定,也就是對於兩個相等的對象返回的hashcode值應該一樣,對於兩個不相等的對象,返回的hashcode值不一定要不同)

hashCode方法

int hashCode()

返回該對象的哈希碼值。

當重寫了equals方法,必須重寫hashcode方法。
這個方法返回一個整型值(hash code value),如果兩個對象被equals()方法判斷爲相等,那麼它們就應該擁有同樣的hash code。Object類的hashCode()方法爲不同的對象返回不同的值,Object類的hashCode值表示的是對象的地址。

hashCode 的常規協定是:
1.在 Java 應用程序執行期間,在對同一對象多次調用 hashCode 方法時,必須一致地返回相同的整數,前提是將對象進行 equals 比較時所用的信息沒有被修改。從某一應用程序的一次執行到同一應用程序的另一次執行,該整數無需保持一致。
2.如果根據 equals(Object) 方法,兩個對象是相等的,那麼對這兩個對象中的每個對象調用 hashCode 方法都必須生成相同的整數結果。
3.如果根據 equals(java.lang.Object) 方法,兩個對象不相等,那麼對這兩個對象中的任一對象上調用 hashCode 方法不要求一定生成不同的整數結果。但是,程序員應該意識到,爲不相等的對象生成不同整數結果可以提高哈希表的性能。

toString方法

String toString()

返回該對象的字符串表示。

當打印引用,如調用System.out.println()時,會自動調用對象的toString()方法,打印出引用所指的對象的toString()方法的返回值,因爲每個類都直接或間接地繼承自Object,因此每個類都有toString()方法。
Object類中的toString()方法定義如下:

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

finalize方法

protected void finalize( )
關鍵字protected是防止在該類之外定義的代碼訪問finalize()標識符。
垃圾回收器準備釋放內存時,回收某個對象時,會先調用該對象的finalize方法。

1 對象不一定會被回收
2 垃圾回收不是析構函數
3 垃圾回收只與內存有關
4 垃圾回收和finalize都是靠不住的,只要JVM還沒有到快耗盡內存的地步,它是不會浪費時間進行垃圾回收的。

有時當撤消一個對象時,需要完成一些操作。例如,如果一個對象正在處理的是非Java 資源,如文件句柄或window 字符字體,這時你要確認在一個對象被撤消以前要保證這些資源被釋放。爲處理這樣的狀況,Java 提供了被稱爲收尾(finalization )的機制。使用該機制你可以定義一些特殊的操作,這些操作在一個對象將要被垃圾回收程序釋放時執行。

在 Java 中,當你創建一個對象時,Java 虛擬機(JVM)爲該對象分配內存、調用構造函數並開始跟蹤你使用的對象。當你停止使用一個對象(就是說,當沒有對該對象有效的引用時),JVM 通過垃圾回收器將該對象標記爲釋放狀態。
當垃圾回收器將要釋放一個對象的內存時,它調用該對象的finalize() 方法(如果該對象定義了此方法)。垃圾回收器以獨立的低優先級的方式運行,只有當其他線程掛起等待該內存釋放的情況出現時,它纔開始運行釋放對象的內存。(事實上,你可以調用System.gc() 方法強制垃圾回收器來釋放這些對象的內存。)

getClass方法

public final Class getClass()
返回一個對象運行時的類。

例子:Student類繼承Person類
這裏寫圖片描述

如果知道一個實例,那麼你可以通過實例的“getClass()”方法獲得該對象的類型類,如果你知道一個類型,那麼你可以使用“.class”的方法獲得該類型的類型類。

notify方法

喚醒在此對象監視器上等待的單個線程。

notifyAll方法

喚醒在此對象監視器上等待的所有線程。

wait方法

void wait() //導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或 notifyAll() 方法。

void wait(long timeout) //導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或notifyAll() 方法,或者超過指定的時間量。

void wait(long timeout, int nanos) //導致當前的線程等待,直到其他線程調用此對象的notify() 方法或 notifyAll() 方法,或者其他某個線程中斷當前線程,或者已超過某個實際時間量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章