欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中Object用法詳解

 更新時間:2023年05月09日 14:22:22   作者:一一哥Sun  
Java是面向對象的編程語言,而在面向對象中,所有的Java類都有一個共同的祖先類,這就是Object,那么Object都有哪些特性呢?今天小編就簡單跟大家分析一下,感興趣的同學可以跟著小編一起學習

一. Object簡介

1. 簡介

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

/**
 * 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類的源碼注釋可以知道,Object類是Java中所有類的父類,相當于是Java中的”萬類之王“,處于最頂層。 所以在Java中,所有的類默認都繼承自Object類。同時Java中的所有類對象,包括數(shù)組,也都要實現(xiàn)這個類中的方法。

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

二. 常用方法

在Object類中,自帶了幾個常用的方法,這幾個方法任意的子類都會繼承,如下圖所示:

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

構造方法;

hashCode()和equals()方法用來判斷對象是否相同;

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

toString()和getClass();

clone();

finalize()

接下來小編就給各位介紹Object類中的幾個常用方法,分別說一下這些方法的功能作用。

1. clone()方法

1.1 clone方法作用

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

1.2 clone源碼分析

我們再看看clone()方法源碼上的注釋,如下圖所示:

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

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

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

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

1.3 Java的淺克隆與深克隆

因為每個類的直接或間接父類都是Object,因此它們都含有clone()方法,但因該方法是protected修飾的,所以我們不能在類外訪問該方法。但如果我們要對一個對象進行復制,可以對clone方法進行復寫,而Java中提供了兩種不同的克隆方式,淺克隆(ShallowClone)深克隆(DeepClone)。

1.3.1 淺克隆

在淺克隆中,如果源對象的成員變量是值類型,則復制一份給克隆對象;如果源對象的成員變量是引用類型,則將引用對象的地址復制一份給克隆對象,也就是說源對象和克隆對象的成員變量指向相同的內存地址。

簡單說,在淺克隆中,當對象被復制時只復制它本身和其中包含的值類型的成員變量,而引用類型的成員對象并沒有復制。我們可以用下圖對淺克隆進行展示:

在Java語言中,通過實現(xiàn)Cloneable接口,默認覆蓋Object類的clone()方法就可以實現(xiàn)淺克隆。

1.3.2 深克隆

在深克隆中,無論源對象的成員變量是值類型還是引用類型,都將復制一份給克隆對象,即深克隆將源對象的所有引用對象也復制一份給克隆對象。

簡單來說,在深克隆中,除了對象本身被復制外,對象中包含的所有成員變量也將復制。我們可以用下圖對深克隆進行展示:

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

2. hashCode()方法

2.1 簡介

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

2.2 hash值

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

  • Java 6、7 中會默認返回一個隨機數(shù);
  • Java 8 中默認通過和當前線程有關的一個隨機數(shù) + 三個確定值,運用Marsaglia’s xorshift scheme的隨機數(shù)算法得到的一個隨機數(shù)。

2.3 案例

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

以上兩個對象的hash值是不同的,表示這是不同的兩個對象。

3. equals(obj)方法

3.1 equals簡介

Object中的equals方法用于判斷this對象和obj本身的值是否相等,即用來判斷調用equals方法的對象和形參obj所引用的對象是否是同一對象。 所謂同一對象,就是指兩個對象是否指向了內存中的同一塊存儲單元地址。如果this和obj指向的是同一塊內存單元地址,則返回true;如果this和obj指向的不是同一塊內存單元地址,則返回false。如果沒有指向同一內存單元,即便是內容完全相等,也會返回false。

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

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

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

3.2 使用原則

我們在使用equals()方法時,需注意下面這些原則:

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

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

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

3.3 基本特性

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

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

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

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

一致性 如果x和y引用的對象沒有發(fā)生變化,反復調用x.equals(y)應該返回同樣的結果;

對于任何非空引用x,x.equals(null)應該返回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對比dog02 "+(dog01==dog02));//false
        //equals()方法的底層默認還是利用==實現(xiàn)的
	System.out.println("dog01對比dog02 "+(dog01.equals(dog02)));//false
    }
}

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

4. getClass()方法

4.1 簡介

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

4.2 案例

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

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

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

5. toString()方法

5.1 簡介

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

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+"狗愛吃骨頭");
    }
    //@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一號="+dog);
	System.out.println("dog二號="+dog.toString());
    }
}

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

從上面程序的運行結果可以發(fā)現(xiàn),默認情況下,對象帶不帶toString()方法,其最終的輸出結果是一樣的,即對象輸出時一定會調用 Object類中的 toString()方法打印內容,所以我們可以利用此特性來通過 toString()方法取得一些對象的信息。

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

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

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

這幾個方法我們后面在分析多線程的面試題時再細說,此處先僅做了解。

7. finalize()方法

7.1 簡介

finalize()方法在進行垃圾回收的時候會用到,主要是在垃圾回收時,用于作為確認該對象是否確認被回收的一個標記。我們在使用finalize()方法時要注意:

  • finalize方法不一定會執(zhí)行,只有在該方法被重寫的時候才會執(zhí)行;
  • finalize方法只會被執(zhí)行一次;
  • 對象可以在finalize方法中獲得自救,避免自己被垃圾回收,同樣的自救也只能進行一次;
  • 不推薦Java程序員手動調用該方法,因為finalize方法代價很大。

7.2 案例

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

/**
 * @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+"狗愛吃骨頭");
    }
	
    //復寫finalize方法
    @Override
    protected void finalize() throws Throwable {
        super.finalize();//不要刪除這行代碼
        System.out.println("finalize方法執(zhí)行了");
    }
}

然后我們對Dog對象進行回收測試:

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

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

三. 結語

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

以上就是Java中Object用法詳解的詳細內容,更多關于Java Object的資料請關注腳本之家其它相關文章!

相關文章

  • java二進制運算基礎知識點詳解

    java二進制運算基礎知識點詳解

    在本文里小編給大家分享了關于java二進制運算基礎知識點以及實例代碼內容,需要的朋友們參考學習下。
    2019-08-08
  • Java String類的性質與比較

    Java String類的性質與比較

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

    Java實現(xiàn)簡單的分頁功能

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

    一個合格JAVA軟件工程師應該具備什么

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

    IDEA中解決 git pull 沖突的方法

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

    關于Openfire集群源碼的分析

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

    淺談Redis持久化的幾種方式

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

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

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

    輸出java進程的jstack信息示例分享 通過線程堆棧信息分析java線程

    通過ps到java進程號將進程的jstack信息輸出。jstack信息是java進程的線程堆棧信息,通過該信息可以分析java的線程阻塞等問題。
    2014-01-01
  • java中的類型擦除type?erasure示例詳解

    java中的類型擦除type?erasure示例詳解

    泛型是java從JDK?5開始引入的新特性,泛型的引入可以讓我們在代碼編譯的時候就強制檢查傳入的類型,從而提升了程序的健壯度,泛型可以用在類和接口上,在集合類中非常常見,本文將會講解泛型導致的類型擦除
    2023-09-09

最新評論