JDK源碼解析之 Java.lang.Object

Object類是Java中其他所有類的祖先,沒有Object類Java面向對象無從談起。作為其他所有類的基類,Object具有哪些屬性和行為,是Java語言設計背后的思維體現。

Object類位于java.lang包中,java.lang包包含著Java最基礎和核心的類,在編譯時會自動導入。Object類沒有定義屬性,一共有13個方法:

1、類構造器public Object();

大部分情況下,Java中通過形如 new A(args…)形式創建一個屬于該類型的對象。其中A即是類名,A(args…)即此類定義中相對應的構造函數。通過此種形式創建的對象都是通過類中的構造函數完成。為體現此特性,Java中規定:在類定義過程中,對于未定義構造函數的類,默認會有一個無參數的構造函數,作為所有類的基類,Object類自然要反映出此特性,在源碼中,未給出Object類構造函數定義,但實際上,此構造函數是存在的。

當然,并不是所有的類都是通過此種方式去構建,也自然的,并不是所有的類構造函數都是public。

2、private static native void registerNatives();

registerNatives函數前面有native關鍵字修飾,Java中,用native關鍵字修飾的函數表明該方法的實現并不是在Java中去完成,而是由C/C++去完成,并被編譯成了.dll,由Java去調用。方法的具體實現體在dll文件中,對于不同平臺,其具體實現應該有所不同。用native修飾,即表示操作系統,需要提供此方法,Java本身需要使用。具體到registerNatives()方法本身,其主要作用是將C/C++中的方法映射到Java中的native方法,實現方法命名的解耦。

既然如此,可能有人會問,registerNatives()修飾符為private,且并沒有執行,作用何以達到?其實,在Java源碼中,此方法的聲明后有緊接著一段靜態代碼塊:

1 private static native void registerNatives();
2 static {
3     registerNatives();
4 }
3、protected native Object clone() throws CloneNotSupportedException;

clone()方法又是一個被聲明為native的方法,因此,我們知道了clone()方法并不是Java的原生方法,具體的實現是有C/C++完成的。clone英文翻譯為"克隆",其目的是創建并返回此對象的一個副本,而克隆出來的副本與原來的對象沒有任何關系的。Java術語表述為:clone函數返回的是一個引用,指向的是新的clone出來的對象,此對象與原對象分別占用不同的堆空間。

4、public final native Class<?> getClass();

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

首先解釋下"類對象"的概念:在Java中,類是是對具有一組相同特征或行為的實例的抽象并進行描述,對象則是此類所描述的特征或行為的具體實例。作為概念層次的類,其本身也具有某些共同的特性,如都具有類名稱、由類加載器去加載,都具有包,具有父類,屬性和方法等。于是,Java中有專門定義了一個類,Class,去描述其他類所具有的這些特性,因此,從此角度去看,類本身也都是屬于Class類的對象。為與經常意義上的對象相區分,在此稱之為"類對象"。

5、public boolean equals(Object obj);

Object類中關于equals()方法的定義:

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

由此可見,Object原生的equals()方法內部調用的正是==,與==具有相同的含義。既然如此,為什么還要定義此equals()方法?

equlas()方法的正確理解應該是:判斷兩個對象是否相等。那么判斷對象相等的標尺又是什么?

如上,在object類中,此標尺即為==。當然,這個標尺不是固定的,其他類中可以按照實際的需要對此標尺含義進行重定義。如String類中則是依據字符串內容是否相等來重定義了此標尺含義。如此可以增加類的功能型和實際編碼的靈活性。當然了,如果自定義的類沒有重寫equals()方法來重新定義此標尺,那么默認的將是其父類的equals(),直到object基類。

6、public native int hashCode();

hashCode()方法返回一個整形數值,表示該對象的哈希碼值。

hashCode()具有如下約定:

1).在Java應用程序程序執行期間,對于同一對象多次調用hashCode()方法時,其返回的哈希碼是相同的,前提是將對象進行equals比較時所用的標尺信息未做修改。在Java應用程序的一次執行到另外一次執行,同一對象的hashCode()返回的哈希碼無須保持一致;

2).如果兩個對象相等(依據:調用equals()方法),那么這兩個對象調用hashCode()返回的哈希碼也必須相等;

3).反之,兩個對象調用hasCode()返回的哈希碼相等,這兩個對象不一定相等。

即嚴格的數學邏輯表示為: 兩個對象相等 <=> equals()相等 => hashCode()相等。因此,重寫equlas()方法必須重寫hashCode()方法,以保證此邏輯嚴格成立,同時可以推理出:hasCode()不相等 => equals()不相等 <=> 兩個對象不相等。

可能有人在此產生疑問:既然比較兩個對象是否相等的唯一條件(也是沖要條件)是equals,那么為什么還要弄出一個hashCode(),并且進行如此約定,弄得這么麻煩?

其實,這主要體現在hashCode()方法的作用上,其主要用于增強哈希表的性能。

以集合類中,以Set為例,當新加一個對象時,需要判斷現有集合中是否已經存在與此對象相等的對象,如果沒有hashCode()方法,需要將Set進行一次遍歷,并逐一用equals()方法判斷兩個對象是否相等,此種算法時間復雜度為o(n)。通過借助于hasCode方法,先計算出即將新加入對象的哈希碼,然后根據哈希算法計算出此對象的位置,直接判斷此位置上是否已有對象即可。(注:Set的底層用的是Map的原理實現)

在此需要糾正一個理解上的誤區:對象的hashCode()返回的不是對象所在的物理內存地址。甚至也不一定是對象的邏輯地址,hashCode()相同的兩個對象,不一定相等,換言之,不相等的兩個對象,hashCode()返回的哈希碼可能相同。

7、public String toString();

toString()方法返回該對象的字符串表示。先看一下Object中的具體方法體:

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

toString()方法我們會經常用到,即使沒有顯式調用,但當我們使用System.out.println(obj)時,其內部也是通過toString()來實現的

toString()是由對象的類型和其哈希碼唯一確定,同一類型但不相等的兩個對象分別調用toString()方法返回的結果可能相同。

8/9/10/11/12、wait(…) / notify() / notifyAll()

wait()、notify/notifyAll() 方法是Object的本地final方法,無法被重寫。這幾個方法主要用于java多線程之間的協作.

wait():調用此方法所在的當前線程等待,直到在其他線程上調用此方法的主調(某一對象)的notify()/notifyAll()方法。

notify/notifyAll() 的執行只是喚醒沉睡的線程,而不會立即釋放鎖,鎖的釋放要看代碼塊的具體執行情況。

wait(long timeout)/wait(long timeout, int nanos):調用此方法所在的當前線程等待,直到在其他線程上調用此方法的主調(某一對象)的notisfy()/notisfyAll()方法,或超過指定的超時時間量。

notify()/notifyAll():喚醒在此對象監視器上等待的單個線程/所有線程。

wait(…) / notify() | notifyAll()一般情況下都是配套使用。

13、protected void finalize();

finalize方法主要與Java垃圾回收機制有關。首先我們看一下finalized方法在Object中的具體定義:

1 protected void finalize() throws Throwable { }

我們發現Object類中finalize方法被定義成一個空方法,為什么要如此定義呢?finalize方法的調用時機是怎么樣的呢?

首先,Object中定義finalize方法表明Java中每一個對象都將具有finalize這種行為,其具體調用時機在:JVM準備對此對形象所占用的內存空間進行垃圾回收前,將被調用。由此可以看出,此方法并不是由我們主動去調用的(雖然可以主動去調用,此時與其他自定義方法無異)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/535794.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/535794.shtml
英文地址,請注明出處:http://en.pswp.cn/news/535794.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

將z-blog改成英文blog所遇到的問題

1.將z-blog中文章日期中的“年,月,日”改成英文 相關模板:b_article-multi.htmlb_article-single.html默認用的時間標簽是<#article/posttime/longdate#> 即 "2007年1月13日" 這樣的形式你可以換成 <#article/posttime/shortdate#>即 "2…

JDK源碼解析之 Java.lang.String

String 類代表字符串。Java 程序中的所有字符串字面值&#xff08;如 “abc” &#xff09;都作為此類的實例實現。 字符串是常量&#xff1b;它們的值在創建之后不能更改。字符串緩沖區支持可變的字符串。因為 String 對象是不可變的&#xff0c;所以可以共享。 一、類定義 p…

看到一個blog的標語,有意思!

"上世紀80年代勇氣&#xff0c;90年代靠關系&#xff0c;現在必須靠知識能力&#xff01;掙錢靠1、興趣廣泛&#xff1b; 2、感覺敏銳&#xff1b; 3、集中力強&#xff1b; 4、個性不脆弱&#xff08;堅韌性&#xff09;&#xff1b; 5、能在瞬間了解因果關系&#xff1b…

JDK源碼解析之 Java.lang.AbstractStringBuilder

這個抽象類是StringBuilder和StringBuffer的直接父類&#xff0c;而且定義了很多方法&#xff0c;因此在學習這兩個類之間建議先學習 AbstractStringBuilder抽象類 該類在源碼中注釋是以JDK1.5開始作為前兩個類的父類存在的&#xff0c;可是直到JDK1.8的API中&#xff0c;關于S…

RHEL下安裝配置基于2臺服務器的MYSQL集群

一、介紹這篇文檔旨在介紹如何在RHEL下安裝配置基于2臺服務器的MySQL集群。并且實現任意一臺服務器出現問題或宕機時MySQL依然能夠繼續運行。 注意&#xff01;雖然這是基于2臺服務器的MySQL集群&#xff0c;但也必須有額外的第三臺服務器作為管理節點&#xff0c;但這臺服務器…

JDK源碼解析之 Java.lang.StringBuffer

StringBuffer類表示一個可變的字符序列。StringBuffer的API與StringBuilder互相兼容&#xff0c;但是StringBuffer是線程安全的。在可能的情況下&#xff0c;建議優先使用StringBuilder&#xff0c;因為在大多數實現中它比StringBuffer更快。 一、類定義 public final class S…

redo和undo

這是在網上看到的對redo和undo的探討&#xff1a; 1. redo 記錄所有做過的事情&#xff0c;用于恢復 undo 記錄事務的前鏡相&#xff0c;用于回滾2. redo&#xff0c;恢復數據庫時&#xff0c;按照重做日志文件來恢復你之前的操作 undo&#xff0c;撤消你做過的操作&#xff0…

JDK源碼解析之 Java.lang.StringBuilder

StringBuilder類表示一個可變的字符序列。StringBuilder的API與StringBuffer互相兼容&#xff0c;但是StringBuilder是非線程安全的&#xff0c;在大多數實現中它比StringBuffer更快。 一、類定義 public final class StringBufferextends AbstractStringBuilderimplements ja…

從映射觀點看索引

信息檢索主要有“檢”與“索&#xff08;辦手續&#xff09;”兩個動作。在圖書館借書時&#xff0c;一般而言&#xff0c; 找書的時間比辦理手續的時間長得多&#xff0c;因而縮短檢查時間是提高效率的關鍵。數據庫中檢 索信息也與此類似。 在沒有索引文件時&#xff0c;DBM…

JDK源碼解析之 Java.lang.Boolean

Boolean 類是將 boolean 基本類型進行包裝。類型為 Boolean 的對象包含一個單一屬性 value&#xff0c;其類型為 boolean。 此外還提供了許多將 boolean 轉換為 String、String 轉換為 boolean&#xff0c;以及其他一些方法。 一、類定義 public final class Boolean implemen…

MYSQL的集群的安裝與配置(mysql-5.1.21)

具體安裝與配置&#xff1a;1&#xff09;準備工作&#xff1a;6臺機器&#xff0c;IP地址分別為192.168.0.&#xff08;231-236&#xff09;MGM節點&#xff1a;192.168.0.231(232)SQL 節點&#xff1a;192.168.0.233-234NDBD 節點&#xff1a;192.168.0.235-236系統都是REDHA…

JDK源碼解析之 Java.lang.Byte

byte&#xff0c;即字節&#xff0c;由8位的二進制組成。在Java中&#xff0c;byte類型的數據是8位帶符號的二進制數,以二進制補碼表示的整數 取值范圍&#xff1a;默認值為0&#xff0c;最小值為-128&#xff08;-27&#xff09;;最大值是127&#xff08;27-1&#xff09; Byt…

在命令行模式下管理SELinux

作者&#xff1a; Oslad.com (原創&#xff01;轉載請注明出處) 2006-07-14 在 GUI 圖形界面模式下&#xff0c;要更改 SELinux 的策略使用方式&#xff0c;只需依次點擊“應用程序”&#xff0c;“系統設置”&#xff0c;“安全級別”&#xff1b;然后在“安全級別配置”對…

JDK源碼解析之 Java.lang.Double

Double類是原始類型double的包裝類&#xff0c;它包含若干有效處理double值的方法&#xff0c;如將其轉換為字符串表示形式&#xff0c;反之亦然。Double類的對象可以包含一個double值。 Double類包裝原始類型的值 double中的對象。類型的對象 Double包含一個類型為的字段 doub…

網頁搜索幫助-禁止搜索引擎收錄的方法

什么是robots.txt文件?搜索引擎使用spider程序自動訪問互聯網上的網頁并獲取網頁信息。spider在訪問一個網站時&#xff0c;會首先會檢查該網站的根域下是否有一個叫做robots.txt的純文本文件。您可以在您的網站中創建一個純文本文件robots.txt&#xff0c;在文件中聲明該網站…

JDK源碼解析之 Java.lang.Float

Float類是原始類型float的包裝類&#xff0c;它包含若干有效處理浮點值的方法&#xff0c;如將其轉換為字符串表示形式&#xff0c;反之亦然。Float類的一個對象可以包含一個浮點值 一、類定義 public final class Float extends Number implements Comparable<Float> {…

FTP兩種工作模式:主動模式(Active FTP)和被動模式(Passive FTP)

在主動模式下&#xff0c;FTP客戶端隨機開啟一個大于1024的端口N向服務器的21號端口發起連接&#xff0c;然后開放N1號端口進行監聽&#xff0c;并向服務器發出PORT N 1命令。服務器接收到命令后&#xff0c;會用其本地的FTP數據端口&#xff08;通常是20&#xff09;來連接客戶…

JDK源碼解析之 java.lang.Integer

teger 基本數據類型int 的包裝類 Integer 類型的對象包含一個 int 類型的字段 一、類定義 public final class Integer extends Number implements Comparable<Integer>{}類被聲明為final的,表示不能被繼承;繼承了Number抽象類,可以用于數字類型的一系列轉換;實現了Comp…

Loadrunner的基本概念

1)vuser_init(only one &#xff0c;重復執行腳本的時候&#xff0c;此部分只會執行一次 ) %G< rJc*P 2)action( 一個或者多個 , 重復執行腳本的時候&#xff0c;只有該部分會按重復的次數重復執行 ) z*Xfjy(Mj 3)vuser_end(only one, 重復執行腳本的時候&#xff0c;此…

JDK源碼解析之 java.lang.Long

Long 與Integer 是數值類型中使用頻率最高的兩個,也是提供支持方法最多的兩個 他們提供出來的方法功能也是高度的相似 一、類定義 public final class Long extends Number implements Comparable<Long> {}類被聲明為final的,表示不能被繼承;繼承了Number抽象類,可以用于…