Java中的Object類

在學習繼承的時候,提到過,所有的類都是直接或者間接地繼承Object類。由此可見,Object類是很重要的一個類。今天就來談談Object類。

類 Object 是類層次結構的根類。每個類都使用 Object 作爲超類。所有對象(包括數組)都實現這個類的方法。
下面來談談Object類中的方法。

構造方法

在這裏插入圖片描述
構造方法是公共的。可以創建對象。

getClass()方法

在這裏插入圖片描述
該方法是一個公共的final的方法。

  • 方法 返回此 Object 的運行時類。返回的 Class 對象是由所表示類的 static synchronized 方法鎖定的對象。
  • 可以通過Class類中的一個方法,獲取對象的真實類的全名稱。
    public String getName();

舉例:

public class Demo {
    public static void main(String[] args) {
        Object o = new Object();
        System.out.println(o.getClass());
    }
}

結果:

class java.lang.Object

hashCode()方法

在這裏插入圖片描述
方法是公共的方法,返回值類型爲int類型。

  • 方法返回該對象的哈希碼值。默認情況下,該方法會根據對象的地址來計算。支持此方法是爲了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。
  • 不同對象的,hashCode()一般來說不會相同。但是,同一個對象的hashCode()值肯定相同。
  • 不是對象的實際地址值,可以理解爲邏輯地址值。

舉例:

public class Demo {
    public static void main(String[] args) {
        Object o = new Object();
        System.out.println(o.hashCode());
    }
}

結果:

460141958

toString()方法

在這裏插入圖片描述
方法爲公共的方法,返回值類型爲String。

  • 返回該對象的字符串表示。
    源代碼:
    public String toString() {
    return getClass().getName() + “@” + Integer.toHexString(hashCode());
    }
  • 它的值等於:
    getClass().getName() + ‘@’ + Integer.toHexString(hashCode())
  • 由於默認情況下的數據對我們來說沒有意義,一般建議重寫該方法。(怎麼重寫, 一般是將該類的所有的成員變量組成返回即可)
  • 在代碼裏,直接輸出對應的名稱,就是調用對象的toString()方法。

舉例:

public class Demo {
    public static void main(String[] args) {
        Object o = new Object();
        System.out.println(o);
    }
}

結果:

java.lang.Object@1b6d3586

重寫toString()方法:

public class Demo {
    public static void main(String[] args) {
        Object o = new Student();
        System.out.println(o);
    }
}

class Student{
    String name;
    int age;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

重寫後的結果爲:

Student{name='null', age=0}

equals()方法

在這裏插入圖片描述
方法爲公共的方法,返回值類型爲boolean類型。

  • 指示其他某個對象是否與此對象“相等”。
    源代碼:
    public boolean equals(Object obj) {
    return (this == obj);
    }
  • 默認情況下比較的是對象的引用是否相同。
  • 由於比較對象的引用沒有意義,一般建議重寫該方法。一般用於比較成員變量的值是否相等。

==和equals()的區別

  • ==:是一個關係運算符,用於比較運算符的兩端是否相等。若爲比較運算符的兩端爲基本數據類型,則比較的是值是否相等;若爲對象,則比較的是對象的地址值是否相等。
  • equals():是一個方法,默認比較的是兩個對象的地址值是否相等。

舉例:

public class Demo {
    public static void main(String[] args) {
        Object o = new Object();
        Object o1 = new Object();
        System.out.println(o.equals(o1));
    }
}

結果:

false

重寫後的equals()方法:

public class Demo {
    public static void main(String[] args) {
        Student s1 = new Student("小明",20);
        Student s2 = new Student("小明",20);
        System.out.println(s1.equals(s2));
    }
}

class Student {
    String name;
    int age;

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }
}

結果爲:

true

clone()方法

在這裏插入圖片描述
方法是受保護的,只能在本類、同一包下(子類和無關類)、不同包下(子類)三種情況下調用clone()方法。

  • 由於clone()的權限修飾符是受保護的,在用的時候,需要讓該類重寫該方法,並把該方法的權限修飾符改爲public。
  • 使用clone()方法採用的是淺克隆的方式。

在這裏插入圖片描述

對象淺克隆要注意的細節

  • 如果一個對象需要調用clone的方法克隆,那麼該對象所屬的類必須要實現Cloneable接口。
  • Cloneable接口只不過是一個標識接口而已,沒有任何方法。
  • 對象的淺克隆就是克隆一個對象的時候,如果被克隆的對象中維護了另外一個類的對象,這時候只是克隆另外一個對象的地址,而沒有把另外一個對象也克隆一份。
  • 對象的淺克隆也不會調用到構造方法的。
    舉例:
public class Demo2 {
    public static void main(String[] args) throws CloneNotSupportedException{
        Teacher teacher = new Teacher("張老師",35);
        Teacher teacher1 = (Teacher) teacher.clone();

    }
}

class Teacher extends Object implements Cloneable{
    
    String name;
    int age;

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

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

    public void show() {
        System.out.println(name);
        System.out.println(age);
    }
}

teacher和teacher1指向的是一模一樣的內存空間,但兩個內存空間的地址值是不一樣的,即改變一個內存空間的變量值不會影響另一個空間的變量的值。
舉例:

public class Demo2 {
    public static void main(String[] args) throws CloneNotSupportedException{
        Teacher teacher = new Teacher("張老師",35);
        teacher.show();
        Teacher teacher1 = (Teacher) teacher.clone();
        teacher1.name="劉老師";
        teacher1.age=30;
        teacher1.show();

    }
}

class Teacher extends Object implements Cloneable{

    String name;
    int age;

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

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

    public void show() {
        System.out.println(name);
        System.out.println(age);
    }
}

結果:

張老師
35
劉老師
30

在這裏插入圖片描述

針對 “對象的淺克隆就是克隆一個對象的時候,如果被克隆的對象中維護了另外一個類的對象,這時候只是克隆另外一個對象的地址,而沒有把另外一個對象也克隆一份。” 這種情況進行分析:
舉例說明:

public class Demo2 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Teacher teacher = new Teacher("張老師", 35);
        teacher.play.name = "打籃球";
        teacher.show();
        Teacher teacher1 = (Teacher) teacher.clone();
        teacher1.name = "劉老師";
        teacher1.age = 30;
        teacher1.play.name = "踢足球";
        teacher1.show();
        teacher.show();


    }
}

class Play {
    String name;

    public Play() {
    }

}

class Teacher extends Object implements Cloneable {

    String name;
    int age;
    Play play = new Play();

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

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

    public void show() {
        System.out.println(name + play.name);
    }
}

結果:

張老師打籃球
劉老師踢足球
張老師踢足球

分析:
在這裏插入圖片描述
對象的深克隆:採用IO流來實現。使用 ObjectOutputStream 將對象寫入文件中,然後再用ObjectInputStream讀取回來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章