淺談Java Object類

今天有空來總結一下Java.lang包中的Object類,若有不當請多指教!html

Object類是Java中其餘全部類的父類。
Object類位於java.lang包中,java.lang包包含着Java最基礎和核心的類,在編譯時會自動導入。
Object類沒有定義屬性,一共有12個方法,具體以下:java

  • registerNatives()
  • clone()
  • getClass()
  • equals(Object obj)
  • hashCode()
  • toString()
  • notify()
  • notifyAll()
  • wait()
  • wait(long timeout)
  • wait(long timeout, int nanos)
  • finalize()

接下來咱們來對這些方法逐個介紹。算法

registerNatives

private static native void registerNatives();
    static {
        registerNatives();
    }

registerNatives函數前面有native關鍵字修飾,Java中,用native關鍵字修飾的函數代表該方法的實現並非在Java中去完成, 而是由C/C++去完成,並被編譯成了.dll,由Java去調用。方法的具體實現體在dll文件中,對於不一樣平臺,其具體實現應該有所不一樣。多線程

clone

protected native Object clone() throws CloneNotSupportedException;

clone函數返回的是一個引用,指向的是新的clone出來的對象,此對象與原對象分別佔用不一樣的堆空間。只有實現了Cloneable接口才能夠調用該方法,不然拋出CloneNotSupportedException異常。Cloneable接口僅是一個表示接口,接口自己不包含任何方法。函數

clone和copy的區別:

假設如今有一個Person對象,Person person1 =new Person("czy",18);一般會有這樣的複製
Person person2=person1,這個時候只是簡單了copy了一下reference,person1和person2都指向內存中同一個object,這樣person1或者person2的一個操做均可能影響到對方。顯然這不是咱們願意看到的。咱們但願獲得tobby的一個精確拷貝,同時二者互不影響,這時候咱們就可使用Clone來知足咱們的需求。
Person person2=person1.clone(),這時會生成一個新的Person對象,而且和person1具備相同的屬性值和方法。性能

getClass

public final native Class<?> getClass();

getClass()也是一個native方法,返回的是此Object對象的類對象/運行時類對象Class<?>。效果與Object.class相同。this

equals

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

能夠看到Object中的equals方法默認使用==進行比較。線程

==和equals的區別:

在Java中有8種基本數據類型:
  - 浮點型:float(4 byte), double(8 byte)
  - 整型:byte(1 byte), short(2 byte), int(4 byte) , long(8 byte)
  - 字符型: char(2 byte)
  - 布爾型: boolean(JVM規範沒有明確規定其所佔的空間大小,僅規定其只可以取字面值"true"和"false")
對於這8種基本數據類型的變量,變量直接存儲的是「值」,所以在用關係操做符==來進行比較時,比較的就是 「值」 自己。code

而對於非基本數據類型的變量,引用類型的變量存儲的並非 「值」自己,而是於其關聯的對象在內存中的地址。htm

總結來講:

  • 對於==,若是做用於基本數據類型的變量,則直接比較其存儲的 「值」是否相等;若是做用於引用類型的變量,則比較的是所指向的對象的地址
  • 對於equals方法,若是沒有對equals方法進行重寫,則比較的是引用類型的變量所指向的對象的地址;諸如String、Date等類對equals方法進行了重寫的話,比較的是所指向的對象的內容。
Java中的約定:重寫equals()方法必須重寫hasCode()方法。

hashcode

public native int hashCode();

hashCode()方法返回一個整形數值,表示該對象的哈希值。
因爲hashCode方法定義在Object類,因此每一個對象都有一個默認的哈希值,其值爲對象的存儲地址。

hashCode()具備以下約定:

  • 在Java應用程序程序執行期間,對於同一對象屢次調用hashCode()方法時,其返回的哈希碼是相同的,前提是沒有重寫equals()方法。
  • 若是兩個對象相等(依據:調用equals()方法),那麼這兩個對象調用hashCode()返回的哈希碼也必須相等;
  • 反之,兩個對象調用hasCode()返回的哈希碼相等,這兩個對象不必定相等。

hashCode()方法主要用於加強哈希表的性能。
以集合類中,以Set爲例,當新加一個對象時,須要判斷現有集合中是否已經存在與此對象相等的對象。
若是沒有hashCode()方法,須要將Set進行一次遍歷,並逐一用equals()方法判斷兩個對象是否相等,此種算法時間複雜度爲o(n)。
經過藉助於hasCode方法,先計算出即將新加入對象的哈希碼,而後根據哈希算法計算出此對象的位置,直接判斷此位置上是否已有對象便可。

toString

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

toString()方法返回該對象的字符串表示。

getClass().getName():返回類對象的名稱
Integer.toHexString(hashCode()):以對象的哈希碼爲實參,以16進制無符號整數形式返回此哈希碼的字符串表示形式。
toString()是由對象的類型和其哈希碼惟一肯定,同一類型但不相等的兩個對象分別調用toString()方法返回的結果可能相同。

wait/notify/notifyAll

這幾個方法主要用於java多線程之間的協做。
在Object類中有三個wait的重載方法:wait() 、wait(long timeout)、wait(long timeout, int nanos)

wait():調用此方法所在的當前線程等待,直到在其餘線程上調用此方法的的notify()/notifyAll()方法。
wait(long timeout)/wait(long timeout, int nanos):調用此方法所在的當前線程等待,直到在其餘線程上調用此方法的notisfy()/notisfyAll()方法,或超過指定的超時時間。
notify()/notifyAll():喚醒在此對象監視器上等待的隨機單個線程/全部線程。

既然是做用於多線程中,爲何倒是Object這個基類所具備的方法?
緣由在於理論上任何對象均可以視爲線程同步中的監聽器,且wait(...)/notify()|notifyAll()方法只能在同步代碼塊中才能使用。

finalize

protected void finalize() throws Throwable { }

finalize方法主要與Java垃圾回收機制有關。

Object中定義finalize方法代表Java中每個對象都將具備finalize這種行爲, 其具體調用時機在:JVM準備對此對對象所佔用的內存空間進行垃圾回收前,將被調用。由此能夠看出,此方法並非由咱們主動去調用的。

參考

https://www.cnblogs.com/lwbqqyumidi/p/3693015.html

相關文章
相關標籤/搜索