亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java中Object用法詳解

 更新時(shí)間:2023年05月09日 14:22:22   作者:一一哥Sun  
Java是面向?qū)ο蟮木幊陶Z(yǔ)言,而在面向?qū)ο笾校械腏ava類(lèi)都有一個(gè)共同的祖先類(lèi),這就是Object,那么Object都有哪些特性呢?今天小編就簡(jiǎn)單跟大家分析一下,感興趣的同學(xué)可以跟著小編一起學(xué)習(xí)

一. Object簡(jiǎn)介

1. 簡(jiǎn)介

在了解Object中的常用方法之前,我們先來(lái)看看Object類(lèi)的源碼,如下所示:

/**
 * Class {@code Object} is the root of the class hierarchy.
 * Every class has {@code Object} as a superclass. All objects,
 * including arrays, implement the methods of this class.
 * @author  unascribed
 * @see     java.lang.Class
 * @since   JDK1.0
 */
public class Object {
    ......

從Object類(lèi)的源碼注釋可以知道,Object類(lèi)是Java中所有類(lèi)的父類(lèi),相當(dāng)于是Java中的”萬(wàn)類(lèi)之王“,處于最頂層。 所以在Java中,所有的類(lèi)默認(rèn)都繼承自O(shè)bject類(lèi)。同時(shí)Java中的所有類(lèi)對(duì)象,包括數(shù)組,也都要實(shí)現(xiàn)這個(gè)類(lèi)中的方法。

所以,Object是Java中所有類(lèi)的父類(lèi)、超類(lèi)、基類(lèi),位于繼承樹(shù)的最頂層??梢哉f(shuō),任何一個(gè)沒(méi)有顯式地繼承別的父類(lèi)的類(lèi),都會(huì)直接繼承Object,否則就是間接地繼承Object,并且任何一個(gè)類(lèi)也都會(huì)享有Object提供的方法。又因?yàn)镺bject是所有類(lèi)的父類(lèi),所以基于多態(tài)的特性,該類(lèi)可以用來(lái)代表任何一個(gè)類(lèi),允許把任何類(lèi)型的對(duì)象賦給 Object類(lèi)型的變量,也可以作為方法的參數(shù)、方法的返回值。

二. 常用方法

在Object類(lèi)中,自帶了幾個(gè)常用的方法,這幾個(gè)方法任意的子類(lèi)都會(huì)繼承,如下圖所示:

根據(jù)上圖,小編把Object類(lèi)中的常用方法歸納為這么幾種:

構(gòu)造方法;

hashCode()和equals()方法用來(lái)判斷對(duì)象是否相同;

wait()、wait(long)、wait(long,int)、notify()、notifyAll();

toString()和getClass();

clone();

finalize()

接下來(lái)小編就給各位介紹Object類(lèi)中的幾個(gè)常用方法,分別說(shuō)一下這些方法的功能作用。

1. clone()方法

1.1 clone方法作用

Object中有兩個(gè)protected修飾的方法,其中一個(gè)就是clone()方法,并且該方法還是一個(gè)native方法。clone()方法用于創(chuàng)建復(fù)制出當(dāng)前類(lèi)對(duì)象的一個(gè)副本,得到一個(gè)復(fù)制對(duì)象。 所謂的復(fù)制對(duì)象,首先會(huì)分配一個(gè)和源對(duì)象(調(diào)用clone方法的對(duì)象)同樣大小的內(nèi)存空間,在這個(gè)內(nèi)存空間中會(huì)創(chuàng)建出一個(gè)新對(duì)象;然后再使用源對(duì)象中對(duì)應(yīng)的各個(gè)成員,填充新對(duì)象的成員,填充完成之后,clone方法會(huì)創(chuàng)建返回一個(gè)新的相同對(duì)象供外部引用。

1.2 clone源碼分析

我們?cè)倏纯碿lone()方法源碼上的注釋,如下圖所示:

從這段注釋中,我們可以了解到:

以x為藍(lán)本創(chuàng)建出的副本,與x對(duì)象并不相同,這保證了克隆出的對(duì)象擁有單獨(dú)的內(nèi)存空間;

源對(duì)象和克隆的新對(duì)象字節(jié)碼相同,它們具有相同的類(lèi)類(lèi)型,但這并不是強(qiáng)制性的;

源對(duì)象和克隆的新對(duì)象利用equals()方法比較時(shí)是相同的,但這也不是強(qiáng)制性的。

1.3 Java的淺克隆與深克隆

因?yàn)槊總€(gè)類(lèi)的直接或間接父類(lèi)都是Object,因此它們都含有clone()方法,但因該方法是protected修飾的,所以我們不能在類(lèi)外訪問(wèn)該方法。但如果我們要對(duì)一個(gè)對(duì)象進(jìn)行復(fù)制,可以對(duì)clone方法進(jìn)行復(fù)寫(xiě),而Java中提供了兩種不同的克隆方式,淺克隆(ShallowClone)深克隆(DeepClone)。

1.3.1 淺克隆

在淺克隆中,如果源對(duì)象的成員變量是值類(lèi)型,則復(fù)制一份給克隆對(duì)象;如果源對(duì)象的成員變量是引用類(lèi)型,則將引用對(duì)象的地址復(fù)制一份給克隆對(duì)象,也就是說(shuō)源對(duì)象和克隆對(duì)象的成員變量指向相同的內(nèi)存地址。

簡(jiǎn)單說(shuō),在淺克隆中,當(dāng)對(duì)象被復(fù)制時(shí)只復(fù)制它本身和其中包含的值類(lèi)型的成員變量,而引用類(lèi)型的成員對(duì)象并沒(méi)有復(fù)制。我們可以用下圖對(duì)淺克隆進(jìn)行展示:

在Java語(yǔ)言中,通過(guò)實(shí)現(xiàn)Cloneable接口,默認(rèn)覆蓋Object類(lèi)的clone()方法就可以實(shí)現(xiàn)淺克隆。

1.3.2 深克隆

在深克隆中,無(wú)論源對(duì)象的成員變量是值類(lèi)型還是引用類(lèi)型,都將復(fù)制一份給克隆對(duì)象,即深克隆將源對(duì)象的所有引用對(duì)象也復(fù)制一份給克隆對(duì)象。

簡(jiǎn)單來(lái)說(shuō),在深克隆中,除了對(duì)象本身被復(fù)制外,對(duì)象中包含的所有成員變量也將復(fù)制。我們可以用下圖對(duì)深克隆進(jìn)行展示:

在Java語(yǔ)言中,如果需要實(shí)現(xiàn)深克隆,可以通過(guò)實(shí)現(xiàn)Cloneable接口,自定義覆蓋Object類(lèi)的clone()方法實(shí)現(xiàn),也可以通過(guò)序列化(Serialization)等方式來(lái)實(shí)現(xiàn)。 如果引用類(lèi)型里面還包含很多引用類(lèi)型,或者內(nèi)層引用類(lèi)型的類(lèi)里面又包含引用類(lèi)型,使用clone方法就會(huì)很麻煩。這時(shí)我們可以用序列化的方式來(lái)實(shí)現(xiàn)對(duì)象的深克隆。

2. hashCode()方法

2.1 簡(jiǎn)介

hashCode()是Object中的一個(gè)native方法,也是所有類(lèi)都擁有的一個(gè)方法,主要是返回每個(gè)對(duì)象十進(jìn)制的hash值。hash值是由hash算法根據(jù)對(duì)象的地址、對(duì)象中的字符串、數(shù)字等計(jì)算出來(lái)的。一般情況下,相同的對(duì)象應(yīng)會(huì)返回相同的哈希嗎值,不同的對(duì)象會(huì)返回不同的哈希碼值。

2.2 hash值

哈希值是根據(jù)地址值換算出來(lái)的一個(gè)值,并不是實(shí)際的地址值,常用于哈希表中,如HashMap、HashTable、HashSet。關(guān)于哈希值,不同的JDK算法其實(shí)是不一樣的:

  • Java 6、7 中會(huì)默認(rèn)返回一個(gè)隨機(jī)數(shù);
  • Java 8 中默認(rèn)通過(guò)和當(dāng)前線程有關(guān)的一個(gè)隨機(jī)數(shù) + 三個(gè)確定值,運(yùn)用Marsaglia’s xorshift scheme的隨機(jī)數(shù)算法得到的一個(gè)隨機(jī)數(shù)。

2.3 案例

Dog dog01=new Dog("喬治01");
Dog dog02=new Dog("喬治02");
//兩個(gè)對(duì)象的hash值是不同的
System.out.println("dog01的hash值 "+dog01.hashCode());
System.out.println("dog02的hash值 "+dog02.hashCode());

以上兩個(gè)對(duì)象的hash值是不同的,表示這是不同的兩個(gè)對(duì)象。

3. equals(obj)方法

3.1 equals簡(jiǎn)介

Object中的equals方法用于判斷this對(duì)象和obj本身的值是否相等,即用來(lái)判斷調(diào)用equals方法的對(duì)象和形參obj所引用的對(duì)象是否是同一對(duì)象。 所謂同一對(duì)象,就是指兩個(gè)對(duì)象是否指向了內(nèi)存中的同一塊存儲(chǔ)單元地址。如果this和obj指向的是同一塊內(nèi)存單元地址,則返回true;如果this和obj指向的不是同一塊內(nèi)存單元地址,則返回false。如果沒(méi)有指向同一內(nèi)存單元,即便是內(nèi)容完全相等,也會(huì)返回false。

Object類(lèi)的equals方法,其作用是比較兩個(gè)對(duì)象是否相同,默認(rèn)比較的是內(nèi)存地址,其底層是通過(guò)==實(shí)現(xiàn)的。如果我們不想比較內(nèi)存地址,那么就需要重寫(xiě)equals方法。默認(rèn)的實(shí)現(xiàn)源碼如下:

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

我們知道,Java中還有一個(gè)==運(yùn)算符,也可以對(duì)兩個(gè)對(duì)象進(jìn)行比較。如果是基本數(shù)據(jù)類(lèi)型,==比較的是它們的值是否相同;如果是引用數(shù)據(jù)類(lèi)型,比較的是它們的內(nèi)存地址是否相同。而equals()方法則是比較兩個(gè)對(duì)象的內(nèi)容是否相等。

3.2 使用原則

我們?cè)谑褂胑quals()方法時(shí),需注意下面這些原則:

(1).equals()只能處理引用類(lèi)型變量;

(2).一般情況下,equals()方法比較的是兩個(gè)引用類(lèi)型變量的地址值是否相等;

(3).但是String類(lèi)、基本類(lèi)型包裝類(lèi)、File類(lèi)、Date類(lèi)等,都重寫(xiě)了Object類(lèi)的equals()方法,比較是兩個(gè)對(duì)象的"具體內(nèi)容"是否相同。

3.3 基本特性

另外Java語(yǔ)言規(guī)范也要求equals方法具有下面的特性:

自反性 對(duì)于任何非空引用x,x.equals(x)應(yīng)該返回true;

對(duì)稱性:對(duì)于任何引用x和y,當(dāng)且僅當(dāng)y.equals(x)返回true,x.equals(y)也應(yīng)該返回true;

傳遞性:對(duì)于任何引用x,y和z,如果x.equals(y)返回true,y.equals(z)返回true,x.equals(z)也應(yīng)該返回true;

一致性 如果x和y引用的對(duì)象沒(méi)有發(fā)生變化,反復(fù)調(diào)用x.equals(y)應(yīng)該返回同樣的結(jié)果;

對(duì)于任何非空引用x,x.equals(null)應(yīng)該返回false。

3.4 案例

/**
 * @author 一一哥Sun
 * 千鋒教育
 */
public class ObjectTest {
    public static void main(String[] args) {
	Dog dog01=new Dog("喬治01");
	Dog dog02=new Dog("喬治02");
	System.out.println("dog01對(duì)比dog02 "+(dog01==dog02));//false
        //equals()方法的底層默認(rèn)還是利用==實(shí)現(xiàn)的
	System.out.println("dog01對(duì)比dog02 "+(dog01.equals(dog02)));//false
    }
}

從上面的案例中,我們也可以證明,equals()方法用于處理引用類(lèi)型的變量,默認(rèn)比較的是兩個(gè)引用類(lèi)型的變量地址是否相等。

4. getClass()方法

4.1 簡(jiǎn)介

getClass()方法可以用于獲取對(duì)象運(yùn)行時(shí)的字節(jié)碼類(lèi)型,得到該對(duì)象的運(yùn)行時(shí)的真實(shí)類(lèi)型。該方法屬于Java的反射機(jī)制,其返回值是Class類(lèi)型,例如 Class c = obj.getClass();。通過(guò)對(duì)象c,我們可以進(jìn)一步獲取該對(duì)象的所有成員方法,每個(gè)成員方法都是一個(gè)Method對(duì)象。我們也可以獲取該對(duì)象的所有成員變量,每個(gè)成員變量都是一個(gè)Field對(duì)象。同樣的,我們也可以獲取該對(duì)象的構(gòu)造函數(shù),構(gòu)造函數(shù)則是一個(gè)Constructor對(duì)象。

4.2 案例

/**
 * @author 一一哥Sun
 * 千鋒教育
 */
public class ObjectTest {
    public static void main(String[] args) {
	//判斷運(yùn)行時(shí)d對(duì)象和c對(duì)象是否是同一個(gè)類(lèi)型
	Animal d = new Dog();
	Animal c = new Cat();

	//方式1:通過(guò)instanceof關(guān)鍵字判斷
	if((d instanceof Dog && c instanceof Dog) ||(d instanceof Cat && c instanceof Cat)) {
            System.out.println("是同一個(gè)類(lèi)型");
	}else {
            System.out.println("不是同一個(gè)類(lèi)型");
	}
		
	//方式2:通過(guò)getClass方法判斷
	if(d.getClass() == c.getClass()) {
            System.out.println("是同一個(gè)類(lèi)型");
	}else {
            System.out.println("不是同一個(gè)類(lèi)型");
	}
    }
}

從上面的代碼案例中,我們可以得知,getClass方法用于返回該對(duì)象的真實(shí)類(lèi)型(運(yùn)行時(shí)的類(lèi)型),可以根據(jù)對(duì)象的字節(jié)碼來(lái)判斷兩個(gè)對(duì)象是否是同一個(gè)對(duì)象。

5. toString()方法

5.1 簡(jiǎn)介

toString()方法可以說(shuō)是一個(gè)進(jìn)行“自我描述”的方法,可以返回某個(gè)對(duì)象的字符串,當(dāng)要輸出某個(gè)實(shí)例對(duì)象的信息時(shí),我們可以通過(guò)重寫(xiě)該方法來(lái)輸出自我描述的信息。該方法通常只是為了方便輸出本類(lèi)的描述信息,比如執(zhí)行System.out.println("xyz")這樣的日志語(yǔ)句。一般情況下,當(dāng)程序要輸出一個(gè)對(duì)象或者把某個(gè)對(duì)象和字符串進(jìn)行連接運(yùn)算時(shí),系統(tǒng)就會(huì)自動(dòng)調(diào)用該對(duì)象的toString()方法返回該對(duì)象的字符串表示。
Object類(lèi)的toString()方法會(huì)返回“運(yùn)行時(shí)的類(lèi)名@十六進(jìn)制哈希碼”格式的字符串,但很多類(lèi)都重寫(xiě)了 Object類(lèi)的toString()方法,用于返回可以表述該對(duì)象信息的字符串。

5.2 案例

/**
 * @author 一一哥Sun
 * 千鋒教育
 */
public class Dog implements Animal{
    private String name;
    public Dog() {}

    public Dog(String name) {
	this.name = name;
    }

    @Override
    public void eat() {
	System.out.println("小狗"+this.name+"狗愛(ài)吃骨頭");
    }
    //@Override
    //public String toString() {	
        //return "Dog name= " + name;
    //}
}

public class ObjectTest {
    public static void main(String[] args) {
	Dog dog=new Dog("喬治");
	System.out.println("dog一號(hào)="+dog);
	System.out.println("dog二號(hào)="+dog.toString());
    }
}

上述代碼執(zhí)行結(jié)果如下圖所示:

從上面程序的運(yùn)行結(jié)果可以發(fā)現(xiàn),默認(rèn)情況下,對(duì)象帶不帶toString()方法,其最終的輸出結(jié)果是一樣的,即對(duì)象輸出時(shí)一定會(huì)調(diào)用 Object類(lèi)中的 toString()方法打印內(nèi)容,所以我們可以利用此特性來(lái)通過(guò) toString()方法取得一些對(duì)象的信息。

6. wait()、wait(long)、wait(long,int)、notify()、notifyAll()方法

這幾個(gè)函數(shù)體現(xiàn)的是Java的多線程機(jī)制,一般是結(jié)合synchronize語(yǔ)句使用。

  • wait()用于讓當(dāng)前線程失去操作權(quán)限,當(dāng)前線程進(jìn)入等待序列;
  • notify()用于隨機(jī)通知一個(gè)持有對(duì)象的鎖的線程獲取操作權(quán)限;
  • wait(long) 和wait(long,int)用于設(shè)定下一次獲取鎖的距離當(dāng)前釋放鎖的時(shí)間間隔;
  • notifyAll()用于通知所有持有對(duì)象的鎖的線程獲取操作權(quán)限。

這幾個(gè)方法我們后面在分析多線程的面試題時(shí)再細(xì)說(shuō),此處先僅做了解。

7. finalize()方法

7.1 簡(jiǎn)介

finalize()方法在進(jìn)行垃圾回收的時(shí)候會(huì)用到,主要是在垃圾回收時(shí),用于作為確認(rèn)該對(duì)象是否確認(rèn)被回收的一個(gè)標(biāo)記。我們?cè)谑褂胒inalize()方法時(shí)要注意:

  • finalize方法不一定會(huì)執(zhí)行,只有在該方法被重寫(xiě)的時(shí)候才會(huì)執(zhí)行;
  • finalize方法只會(huì)被執(zhí)行一次;
  • 對(duì)象可以在finalize方法中獲得自救,避免自己被垃圾回收,同樣的自救也只能進(jìn)行一次;
  • 不推薦Java程序員手動(dòng)調(diào)用該方法,因?yàn)閒inalize方法代價(jià)很大。

7.2 案例

為了測(cè)試出finalize()方法的作用,小編給大家設(shè)計(jì)了如下案例:

/**
 * @author 一一哥Sun
 * 千鋒教育
 */
public class Dog implements Animal{
    private String name;
    public Dog() {}

    public Dog(String name) {
	this.name = name;
    }

    @Override
    public void eat() {
	System.out.println("小狗"+this.name+"狗愛(ài)吃骨頭");
    }
	
    //復(fù)寫(xiě)finalize方法
    @Override
    protected void finalize() throws Throwable {
        super.finalize();//不要?jiǎng)h除這行代碼
        System.out.println("finalize方法執(zhí)行了");
    }
}

然后我們對(duì)Dog對(duì)象進(jìn)行回收測(cè)試:

public class ObjectTest {
    public static void main(String[] args) {
	Dog dog=new Dog("喬治");
	//手動(dòng)將對(duì)象標(biāo)記為垃圾對(duì)象
        dog = null;
        //觸發(fā)垃圾回收器,回收垃圾對(duì)象
        System.gc();	
    }
}

要想確保finalize()方法的執(zhí)行,我們首先需要在相關(guān)對(duì)象中重新finalize()方法,然后將待回收的對(duì)象手動(dòng)標(biāo)記為null,最后再手動(dòng)調(diào)用gc()方法,這樣才有可能確保finalize()方法一定執(zhí)行。

三. 結(jié)語(yǔ)

至此,就把Object類(lèi)給大家介紹完畢了,這個(gè)類(lèi)的內(nèi)容并不是很難,主要是掌握幾個(gè)常用的方法就可以了,尤其是equals()、hashCode()、toString()、getClass()等方法。

以上就是Java中Object用法詳解的詳細(xì)內(nèi)容,更多關(guān)于Java Object的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java二進(jìn)制運(yùn)算基礎(chǔ)知識(shí)點(diǎn)詳解

    java二進(jìn)制運(yùn)算基礎(chǔ)知識(shí)點(diǎn)詳解

    在本文里小編給大家分享了關(guān)于java二進(jìn)制運(yùn)算基礎(chǔ)知識(shí)點(diǎn)以及實(shí)例代碼內(nèi)容,需要的朋友們參考學(xué)習(xí)下。
    2019-08-08
  • Java String類(lèi)的性質(zhì)與比較

    Java String類(lèi)的性質(zhì)與比較

    字符串廣泛應(yīng)用 在 Java 編程中,在 Java 中字符串屬于對(duì)象,Java 提供了 String 類(lèi)來(lái)創(chuàng)建和操作字符串,本文將為你帶來(lái)詳細(xì)介紹,感興趣的朋友繼續(xù)往下看吧
    2021-10-10
  • Java實(shí)現(xiàn)簡(jiǎn)單的分頁(yè)功能

    Java實(shí)現(xiàn)簡(jiǎn)單的分頁(yè)功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單的分頁(yè)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 一個(gè)合格JAVA軟件工程師應(yīng)該具備什么

    一個(gè)合格JAVA軟件工程師應(yīng)該具備什么

    一個(gè)合格JAVA軟件工程師應(yīng)該具備哪些專業(yè)技能,面試技巧是什么?本文為大家分享了2016版最新Java軟件工程師就業(yè)思維圖,感興趣的小伙伴們可以參考一下
    2016-11-11
  • IDEA中解決 git pull 沖突的方法

    IDEA中解決 git pull 沖突的方法

    這篇文章主要介紹了IDEA中解決 git pull 沖突的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 關(guān)于Openfire集群源碼的分析

    關(guān)于Openfire集群源碼的分析

    這篇文章主要介紹了關(guān)于Openfire集群源碼的分析,內(nèi)容比較詳細(xì),具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-09-09
  • 淺談Redis持久化的幾種方式

    淺談Redis持久化的幾種方式

    這篇文章主要介紹了淺談Redis持久化的幾種方式,前面說(shuō)到了Redis持久化的 實(shí)現(xiàn)方式主要分為了:快照持久化(RDB)、寫(xiě)日志持久化(AOF)
    ,其中快照持久化方式也就是RDB ,需要的朋友可以參考下
    2023-08-08
  • Java實(shí)現(xiàn)高校教務(wù)系統(tǒng)

    Java實(shí)現(xiàn)高校教務(wù)系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)高校教務(wù)系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 輸出java進(jìn)程的jstack信息示例分享 通過(guò)線程堆棧信息分析java線程

    輸出java進(jìn)程的jstack信息示例分享 通過(guò)線程堆棧信息分析java線程

    通過(guò)ps到j(luò)ava進(jìn)程號(hào)將進(jìn)程的jstack信息輸出。jstack信息是java進(jìn)程的線程堆棧信息,通過(guò)該信息可以分析java的線程阻塞等問(wèn)題。
    2014-01-01
  • java中的類(lèi)型擦除type?erasure示例詳解

    java中的類(lèi)型擦除type?erasure示例詳解

    泛型是java從JDK?5開(kāi)始引入的新特性,泛型的引入可以讓我們?cè)诖a編譯的時(shí)候就強(qiáng)制檢查傳入的類(lèi)型,從而提升了程序的健壯度,泛型可以用在類(lèi)和接口上,在集合類(lèi)中非常常見(jiàn),本文將會(huì)講解泛型導(dǎo)致的類(lèi)型擦除
    2023-09-09

最新評(píng)論