Java Object詳解

來源:互聯網
上載者:User

標籤:

我們都知道:在Java中,所有的類都繼承了Object這個基類,並且大家都知道,Object有幾個比較通用的方法,如equals(),clone(),toString(),我們需要在使用它們的時候進行覆寫,今天,我們就具體的探究下這幾個方法。

void registerNatives()

這是個Native方法,在靜態塊中調用,其目的是將hashCode,wait,notify,notifyAll和clone方法註冊到本地。

Class<?> getClass()

同樣是個Native方法,擷取對象的Class。

int hashCode()

Native方法,產生雜湊碼,其中注意三點

  • 一個對象在同一個進程被多次調用,但是它的雜湊碼仍然應該是相同的。但是,當同一個對象在不同進程中執行,則雜湊碼有可能不同。JavaDoc原文如下

    Whenever it is invoked on the same object more than once during an execution of a Java application, the {@code hashCode} method must consistently return the same integer, provided no information used in {@code equals} comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.

  • 如果兩個對象通過equals()比較返回true,那麼它們的雜湊碼應該相同。

  • 如果兩個對象通過equals()比較返回false,那麼它們的雜湊碼應該不同。

boolean equals(Object obj)

這恐怕使我們最常用的方法之一了,我們在實際應用中,也經常遇到什麼時候用equals(),什麼時候用==的問題。一般來說,基礎資料型別 (Elementary Data Type)用==,因為這樣可以直接比較它們的值,但是複合資料型別如果我們用==的話,那麼實際上我們比較的就是它們的引用了,除非它們指向的是同一個對象,否則它們不可能相等,因此我們比較符合資料類型一般用equals(),並且我們應該覆寫equals(),這是因為Object的equals()方法預設的也是用==進行判定:

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

我們再來看看我們經常用的String是如何覆寫equals()方法的:

public boolean equals(Object anObject) {    if (this == anObject) {        return true;    }    if (anObject instanceof String) {        String anotherString = (String)anObject;        int n = value.length;        if (n == anotherString.value.length) {            char v1[] = value;            char v2[] = anotherString.value;            int i = 0;            while (n-- != 0) {                if (v1[i] != v2[i])                    return false;                i++;            }            return true;        }    }    return false;}

在這裡還有一個很有趣的問題,請看下面的例子

    String s1 = "String";    String s2 = "String";    System.out.println("The result is " + s1.equals(s2));

你會發現傳回值為True,這個就和我們上面講的不一樣了,按照我們上面的講解,這時候應該返回false才對。其實是這樣的,因為JVM中會維護一個字串池,如果池中已經有包含此對象的字串的時候,那麼它就會返回池中的字串(當然如果你new一個新的String對象的話就另當別論。)所以這個時候返回的是true。

Object clone()

Native方法,我們一般用它來複製一個對象,並且用clone()可以實現深複製(將所有需要複製的對象都複製了一遍,而不單單是用引用指向原來的對象。)樣本如下:

public class Animal implements Cloneable {    private int height;    private int age;    public Animal(int height, int age){        this.height = height;        this.age = age;    }    @Override    public Object clone() throws CloneNotSupportedException {        return super.clone();    }    @Override    public String toString() {        return "Animal{" +                "height=" + height +                ", age=" + age +                ‘}‘;    }    public int getHeight() {        return height;    }    public void setHeight(int height) {        this.height = height;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}public class People implements Cloneable {    private int height;    private int age;    private Animal a;    public People(int height, int age,Animal a){        this.height = height;        this.age = age;        this.a = a;    }    @Override    public Object clone() throws CloneNotSupportedException {        People p = (People) super.clone();        p.a = (Animal) a.clone();        return p;    }    @Override    public String toString() {        return "People{" +                "height=" + height +                ", age=" + age +                ", a=" + a +                ‘}‘;    }    public int getHeight() {        return height;    }    public void setHeight(int height) {        this.height = height;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public void setAnimalAge(int a) {        this.a.setAge(5);    }}

接下來我們這樣調用:

    Animal a1 = new Animal(100,3);    People p1 = new People(173,24,a1);    People p2 = (People) p1.clone();    p2.setAge(26);    p2.setHeight(181);    p2.setAnimalAge(6);    System.out.println(p1.toString());    System.out.println(p2.toString());

這樣我們就完成深複製了。

String toString()

最常用的方法,我們一般用它擷取對象成員變數的值。Object的預設實現:

public String toString() {    return getClass().getName() + "@" + Integer.toHexString(hashCode());}
void notify(),void notifyAll()

Native方法,多線程時應用,通知其他線程等待結束。

void wait(long),void wait(long,int),void wait()

Native方法,通知線程等待。

void finalize()

記憶體回收。當JVM判斷一個對象可以被記憶體回收時,那麼JVM會調用finalize()方法,但是記住,它只能調用一次(所以如果你想這個對象不被垃圾清除的話,你就要在這裡面做點事情了),但是一般你不能依賴在這裡做記憶體回收的工作,在《Java編程思想》中說明了有關finalize()的一個用法,那就是通過finalize()來進行對象終結對象的判斷。

Java Object詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.