Java基礎--常用API--java.lang.Object


一、簡述

  1、Object類是所有類的父類,即直接或間接的繼承java.lang.Object類。省略了extends Object。

 

  2、方法

    (1)protected native Object clone() throws CloneNotSupportedException; //創建並返回一個對象的副本。

    (2)public String toString();  //返回一個字符串,一般需要重寫。

    (3)public final native Class<?> getClass();  //返回對象在運行時的類的類型

    (4)public boolean equals(Object obj);  //用來判斷調用equals對象與參數對象obj是否為同一個對象,一般需重寫。

    (5)public native int hashCode(); //返回對象的哈希碼,可用於哈希查找,減少equals比較的次數,一般重寫equals方法后也要重寫hashcode方法。

    (6)protected void finalize() throws Throwable { }; //該方法用於釋放資源,無法確定該方法什么時候被調用。

    (7)public final native void wait(long timeout) throws InterruptedException; //使當前線程等待鎖,直到獲取鎖或被中斷,timeout指的是最長等待時間。

    (8)public final native void notify(); //用於隨機喚醒該對象上等待的某個線程。

    (9)public final native void notifyAll(); //用於喚醒該對象上等待的所有線程。

 

  3、由於getClass()、notify()、notifyAll()、wait()等方法被final修飾,所以不能被重寫。

 

二、Clone()

  1、clone()方法作用是返回一個Object對象的復制,且復制的對象是一個新的對象。

  

  2、使用clone()方法時,需要實現Cloneable接口,否則會拋出異常(CloneNotSupportedException)。

 

  3、分類:淺復制(Shallow Clone)與深復制(Deep Clone)

    (1)淺復制:復制后的對象的所有變量都與原有對象的值相同,且所有對其他對象的引用仍指向原來的對象。簡單的講,對於基本類型,復制的是數據,對於引用類型,復制的是數據的地址。即淺復制復制當前對象,不復制當前對象中的引用對象。

      注意一個坑:對於引用類型,復制的是數據的地址(通過地址訪問對象的真實數據)。若通過地址來修改對象,那么原有對象以及復制的對象均會修改相應的值。但若是修改了地址(比如new了一個對象,則地址發生改變,而原有的對象並未發生改變),則只有被修改的對象才會發生改變。

    (2)深復制:指的是完全復制,將當前對象整體復制,並創建一個新的對象保存。即深復制復制當前對象,且復制當前對象中的引用對象。簡單的講,深復制在淺復制的基礎上,將引用類型再復制一份,其中引用類型需要實現Cloneable接口(如下例中的People類實現了Cloneable接口)。

      注意一個坑:只有實現了Cloneable接口,才能調用clone()方法。

/**
 * 引用類型,用於測試淺復制與深復制的差別。 若只是淺復制,不用實現Clonable接口。 若是深復制,則要實現Cloneable接口以及clone方法。
 */
class People implements Cloneable {
    private String name;
    private int age;

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "People [name=" + name + ", age=" + age + "]";
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

/**
 * 淺復制
 */
class ShallowCloneDemo implements Cloneable {
    private People people;
    private String sex;

    public ShallowCloneDemo(People people, String sex) {
        this.people = people;
        this.sex = sex;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public People getPeople() {
        return people;
    }

    public void setPeople(People people) {
        this.people = people;
    }

    @Override
    protected Object clone() {
        try {
            return (ShallowCloneDemo) super.clone();
        } catch (CloneNotSupportedException e) {
            System.out.println("Shallow Clone Error");
            return null;
        }
    }

    @Override
    public String toString() {
        return "ShallowCloneDemo [people=" + people + ", sex=" + sex + "]";
    }
}

/**
 * 深復制
 */
class DeepCloneDemo implements Cloneable {
    private People people;
    private String sex;

    public DeepCloneDemo(People people, String sex) {
        this.people = people;
        this.sex = sex;
    }

    public People getPeople() {
        return people;
    }

    public void setPeople(People people) {
        this.people = people;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    protected Object clone() {
        DeepCloneDemo obj = null;
        try {
            obj = (DeepCloneDemo) super.clone();// 淺復制
            obj.people = (People) this.getPeople().clone();// 需要克隆引用類型
        } catch (CloneNotSupportedException e) {
            System.out.println("Deep Clone Error");
            return null;
        }
        return obj;
    }

    @Override
    public String toString() {
        return "DeepCloneDemo [people=" + people + ", sex=" + sex + "]";
    }

}

/**
 * 測試類,用於測試淺復制與深復制
 */
public class Test {
    public static void main(String[] args) {
        System.out.println("普通實例化一個ShallowCloneDemo:");
        ShallowCloneDemo shallowCloneDemo1 = new ShallowCloneDemo(new People("rick", 18), "man");
        System.out.println("實例化完成");
        System.out.println();

        System.out.println("通過clone()方法淺復制克隆一個ShallowCloneDemo:");
        System.out.println("Start Shallow Cloning");
        ShallowCloneDemo shallowCloneDemo2 = (ShallowCloneDemo) shallowCloneDemo1.clone();
        System.out.println("Shallow Clone End");
        System.out.println();

        System.out.println("輸出原有對象以及淺復制克隆對象的值:");
        System.out.println(shallowCloneDemo1);
        System.out.println(shallowCloneDemo2);
        System.out.println();

        System.out.println("對原有對象進行修改后,輸出原有對象以及淺復制克隆對象的值:");
        shallowCloneDemo1.getPeople().setName("tom");
        shallowCloneDemo2.getPeople().setAge(20);
        shallowCloneDemo1.setSex("woman");
        System.out.println(shallowCloneDemo1);
        System.out.println(shallowCloneDemo2);
        System.out.println("結果顯示,淺復制對象會隨着原有對象一起修改。");
        System.out.println("這里由於String類型相當於指向了一個新地址,所以只有被修改的對象改變值");
        System.out.println();

        System.out.println("普通實例化一個DeepCloneDemo:");
        DeepCloneDemo deepCloneDemo1 = new DeepCloneDemo(new People("rick", 18), "man");
        System.out.println("實例化完成");
        System.out.println();

        System.out.println("通過clone()方法深復制克隆一個DeepCloneDemo:");
        System.out.println("Start Deep Cloning");
        DeepCloneDemo deepCloneDemo2 = (DeepCloneDemo) deepCloneDemo1.clone();
        System.out.println("Deep Clone End");
        System.out.println();

        System.out.println("輸出原有對象以及深復制克隆對象的值:");
        System.out.println(deepCloneDemo1);
        System.out.println(deepCloneDemo2);
        System.out.println();

        System.out.println("對原有對象進行修改后,輸出原有對象以及淺復制克隆對象的值:");
        deepCloneDemo1.getPeople().setName("tom");
        deepCloneDemo2.getPeople().setAge(20);
        deepCloneDemo1.setSex("woman");
        System.out.println(deepCloneDemo1);
        System.out.println(deepCloneDemo2);
        System.out.println("結果顯示,深復制時對象是獨立的,互不干擾。");
        System.out.println("這里由於String類型相當於指向了一個新地址,所以只有被修改的對象改變值");
    }
}
/*
測試結果:
普通實例化一個ShallowCloneDemo:
實例化完成

通過clone()方法淺復制克隆一個ShallowCloneDemo:
Start Shallow Cloning
Shallow Clone End

輸出原有對象以及淺復制克隆對象的值:
ShallowCloneDemo [people=People [name=rick, age=18], sex=man]
ShallowCloneDemo [people=People [name=rick, age=18], sex=man]

對原有對象進行修改后,輸出原有對象以及淺復制克隆對象的值:
ShallowCloneDemo [people=People [name=tom, age=20], sex=woman]
ShallowCloneDemo [people=People [name=tom, age=20], sex=man]
結果顯示,淺復制對象會隨着原有對象一起修改。
這里由於String類型相當於指向了一個新地址,所以只有被修改的對象改變值

普通實例化一個DeepCloneDemo:
實例化完成

通過clone()方法深復制克隆一個DeepCloneDemo:
Start Deep Cloning
Deep Clone End

輸出原有對象以及深復制克隆對象的值:
DeepCloneDemo [people=People [name=rick, age=18], sex=man]
DeepCloneDemo [people=People [name=rick, age=18], sex=man]

對原有對象進行修改后,輸出原有對象以及淺復制克隆對象的值:
DeepCloneDemo [people=People [name=tom, age=18], sex=woman]
DeepCloneDemo [people=People [name=rick, age=20], sex=man]
結果顯示,深復制時對象是獨立的,互不干擾。
這里由於String類型相當於指向了一個新地址,所以只有被修改的對象改變值
*/

 

三、toString、getClass

  1、Object 類的 toString 方法返回一個字符串,該字符串由類名、標記符“@”和此對象哈希碼的無符號十六進制表示組成

 

  2、Object 類的getClass()方法返回一個對象的類名。

 

四、equals、hashcode

  1、Object中的equals方法是直接判斷this和obj本身的值是否相等,即用來判斷調用equals的對象和形參obj所引用的對象是否是同一對象(即是否占據同一個內存)。對於內容相同但內存不同的對象,返回false。需要進行重寫,並重寫比較規則,才能使其為true。

 

  2、Object的hashcode()方法用於哈希查找,可以減少在查找中使用equals的次數,重寫了equals方法一般都要重寫hashCode方法。

 

五、==和equals的區別是什么?

  1、==對於基本類型,比較的是值,對於引用類型,比較的引用變量的堆內存地址。

 

  2、equals未重寫時等價於==,一般重寫后用來比較兩個對象的內容是否相等。

 

六、hashCode() 與 equals() 的關系?

  1、hashcode()的作用用於獲取哈希碼(散列碼),其返回一個int整數,用於確定對象在哈希表中的索引位置。


  2、equals相同的兩個對象的hashCode必定相同。


  3、hashCode相同的兩個對象的equal不一定相同。


  4、equals重寫時,hashcode一般需重寫。hashcode默認為堆中對象產生的獨特值,若未重寫hashcode,那么即使兩個對象指向同一個數據,hashcode值也不會相等。


  5、hashcode與equals在HashSet中的應用,當對象加入HashSet時,先由hashcode計算對象的散列值,若相等,則比較equals,若equals比較仍相等(即為相同對象),則對象不會加入到HashSet中。若equals比較不等,則將對象重新散列到其他位置。通過減少equals比較次數,可以提高執行速度。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM