日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

作为所有类的顶层父类,没想到Object的魔力如此之大!

發(fā)布時間:2024/1/16 windows 72 coder
生活随笔 收集整理的這篇文章主要介紹了 作为所有类的顶层父类,没想到Object的魔力如此之大! 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

寫在開頭

在上一篇博文中我們提到了Java面向?qū)ο蟮乃拇筇匦裕渲姓劶啊俺橄蟆碧匦詴r做了一個引子,引出今天的主人公Object,作為所有類的*父類,Object被視為是James.Gosling的哲學(xué)思考,它高度概括了事務(wù)的自然與社會行為。

源碼分析

跟進Object類的源碼中我們可以看到,類的注釋中對它做了一個總結(jié)性的注釋。

在Object的內(nèi)部主要提供了這樣的11種方法,大家可以在源碼中一個個的跟進去看,每個方法上均有詳細的英文注釋,養(yǎng)成良好的看英文注釋習(xí)慣,是一個合格程序員的必備基礎(chǔ)技能哈。

/**
 * 方法一
 */
public final native Class<?> getClass()
/**
 * 方法二
 */
public native int hashCode()
/**
 *方法三
 */
public boolean equals(Object obj)
/**
 * 方法四
 */
protected native Object clone() throws CloneNotSupportedException
/**
 * 方法五
 */
public String toString()
/**
 * 方法六
 */
public final native void notify()
/**
 * 方法七
 */
public final native void notifyAll()
/**
 * 方法八
 */
public final native void wait(long timeout) throws InterruptedException
/**
 * 方法九
 */
public final void wait(long timeout, int nanos) throws InterruptedException
/**
 * 方法十
 */
public final void wait() throws InterruptedException
/**
 * 方法十一
 */
protected void finalize() throws Throwable { }

getClass()

getClass()是Java的一個native 方法,用于返回當(dāng)前運行時對象的 Class 對象,使用了 final 關(guān)鍵字修飾,故不允許子類重寫。在源碼中我們可以到,該方法的返回是Class類。
Class 類存放類的結(jié)構(gòu)信息,能夠通過 Class 對象的方法取出相應(yīng)信息:類的名字、屬性、方法、構(gòu)造方法、父類、接口和注解等信息。

hashCode()

同樣是native 方法,用于返回對象的哈希碼,主要使用在哈希表中,比如 JDK 中的HashMap。

equals()

默認比較對象的地址值是否相等,子類可以重寫比較規(guī)則,如String 類對該方法進行了重寫以用于比較字符串的值是否相等。

clone()

native 方法,用于創(chuàng)建并返回當(dāng)前對象的一份拷貝。

toString()

返回類的名字實例的哈希碼的 16 進制的字符串。建議 Object 所有的子類都重寫這個方法。

notify()

native 方法,并且不能重寫。喚醒一個在此對象監(jiān)視器上等待的線程(監(jiān)視器相當(dāng)于就是鎖的概念)。如果有多個線程在等待只會任意喚醒一個。

notifyAll()

native 方法,并且不能重寫。跟 notify 一樣,唯一的區(qū)別就是會喚醒在此對象監(jiān)視器上等待的所有線程,而不是一個線程。

wait(long timeout)

native方法,并且不能重寫。暫停線程的執(zhí)行。注意:sleep 方法沒有釋放鎖,而 wait 方法釋放了鎖 ,timeout 是等待時間。

wait(long timeout, int nanos)

多了 nanos 參數(shù),這個參數(shù)表示額外時間(以納秒為單位,范圍是 0-999999)。 所以超時的時間還需要加上 nanos 納秒。

wait()

讓持有對象鎖的線程進入等待,不可設(shè)置超時時間,沒有被喚醒的情況下,會一直等待。

finalize()

實例被垃圾回收器回收的時候觸發(fā)的操作

高頻面試考點總結(jié)

雖然在日常的代碼開發(fā)中,我們很少會直接使用Object類,但考慮到它的獨特地位,與此相關(guān)的面試考點還是不少的,我們今天總結(jié)一下。

1.淺拷貝、深拷貝、引用拷貝的區(qū)別?

淺拷貝:基本類型的屬性會直接復(fù)制一份,而引用類型的屬性復(fù)制:復(fù)制棧中的變量和變量指向堆內(nèi)存中的對象的指針,不復(fù)制堆內(nèi)存中的對象,也就是說拷貝對象和原對象共用同一個內(nèi)部對象。

深拷貝:深拷貝會完全復(fù)制整個對象,包括這個對象所包含的內(nèi)部對象。

引用拷貝:簡單來說,引用拷貝就是兩個不同的引用指向同一個對象。

2.Java中如何實現(xiàn)淺拷貝與深拷貝

其實實現(xiàn)淺拷貝很簡單,實現(xiàn) Cloneable 接口,重寫 clone() 方法,在clone()方法中調(diào)用父類Object的clone()方法。

public class TestClone {
 
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person(1, "ConstXiong");//創(chuàng)建對象 Person p1
        Person p2 = (Person)p1.clone();//克隆對象 p1
        p2.setName("其不答");//修改 p2的name屬性,p1的name未變
        System.out.println(p1);
        System.out.println(p2);
    }
    
}
 
/**
 * person類
 */
class Person implements Cloneable {
    
    private int pid;
    
    private String name;
    
    public Person(int pid, String name) {
        this.pid = pid;
        this.name = name;
        System.out.println("Person constructor call");
    }
 
    public int getPid() {
        return pid;
    }
 
    public void setPid(int pid) {
        this.pid = pid;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
 
    @Override
    public String toString() {
        return "Person [pid:"+pid+", name:"+name+"]";
    }
    
}

那么如何實現(xiàn)深拷貝呢,這里給出兩種方法
方法一:將對象的屬性的Class 也實現(xiàn) Cloneable 接口,在克隆對象時也手動克隆屬性。
方法二:結(jié)合序列化(JDK java.io.Serializable 接口、JSON格式、XML格式等),完成深拷貝。

3.==和equals的區(qū)別是什么?

**區(qū)別**
== 是關(guān)系運算符,equals() 是方法,結(jié)果都返回布爾值
Object 的 == 和 equals() 比較的都是地址,作用相同

**== 作用:**
基本類型,比較值是否相等
引用類型,比較內(nèi)存地址值是否相等
不能比較沒有父子關(guān)系的兩個對象

**equals()方法的作用:**
JDK 中的類一般已經(jīng)重寫了 equals(),比較的是內(nèi)容
自定義類如果沒有重寫 equals(),將調(diào)用父類(默認 Object 類)的 equals() 方法,Object 的 equals() 比較使用了 this == obj
可以按照需求邏輯,重寫對象的 equals() 方法(重寫 equals 方法,一般須重寫 hashCode 方法)

4.為什么說重寫equals方法也要重寫hashCode方法呢?

equals()方法是用來判斷兩個對象是否相等的重要方法,Object中默認比較地址,但這在實際使用上意義不大,比如兩個字符串,我們比較的初衷肯定是他們的字符串內(nèi)容是否相等,而不是內(nèi)存地址,典型的就是String內(nèi)部的重寫equals。

hashCode()方法是一個C或C++實現(xiàn)的本地方法,用以獲取對象的哈希碼值(散列碼),通過碼值可以確定該對象在哈希表中的索引位置,是通過線程局部狀態(tài)來實現(xiàn)的隨機數(shù)值。子類可通過重寫該方法去重新設(shè)計hash值。
使用hashCode方法可以一定程度上判斷兩個對象是否相等,因為,若兩個對象相等,那么他們所在的索引位置肯定就一樣,這時hashCode獲取的哈希碼自然也就一樣,但這個條件反過來就不一定成立了,哈希碼相等的兩個對象不一定相等,因為存在哈希碰撞

看完這兩個方法的特點,我們大概可以明白了,確保兩個對象是否真正相等,需要這個兩個方法的協(xié)作,equals是邏輯上的相等,hashCode是物理上的相等,若我們在重寫equals()方法時,不去重寫配套的hashCode方法,就會導(dǎo)致兩個對象在邏輯上相等,但物理上不等,這會帶來很多問題,譬如集合類HashMap的底層實現(xiàn)是數(shù)據(jù)+鏈表/紅黑樹的方式,通過計算hash尋找位置,通過equals判斷元素相等,這時候若僅重寫equals的話,hash不重寫,就會出現(xiàn)邏輯上我們認為相等的兩個數(shù),存在了不同的位置上,造成混亂的場面。

總結(jié)

以上是生活随笔為你收集整理的作为所有类的顶层父类,没想到Object的魔力如此之大!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。