JAVA----Object類

java.lang.Object是JAVA中所有類層次結構的根,所有的對象包括數組都實現了Object類的方法。


構造器:

public Object()

方法:

1. clone()

該方法需要實現Cloneable接口,重寫clone方法才能使用;
該方法會返回一個一摸一樣的對象,但是該對象不等同於原來的對象
x.clone() != x;
例如:

class Person implements Cloneable{
    public String name;
    public int age;
    public Person(String name,int age ) {
        this.age = age;
    }
    public Person clone() throws CloneNotSupportedException {
        return (Person) super.clone();
    }
}
public class Run{
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person("小明",18);
        Person p2 =  p1.clone();
        Person p3 = p1;
        System.out.println(p1.hashCode());
        System.out.println(p2.hashCode());
        System.out.println(p1==p2);
        System.out.println(p1==p3); 
    }
}

輸出:
//後面的只是人爲加的註解

366712642    //p1的hashCode
1829164700   //p2的hashCode
false        //p1==p2
true         //p1==p3

該方法是完全克隆了一個對象,並不僅僅是創建一個引用指向原來的對象。
但是需要注意,如果一個對象裏面的屬性包含引用的話,那麼該引用屬性也要實現Cloneable接口,因爲引用在內存中存儲的只是引用對象的hash值,克隆也只是克隆了hash值而已。

例如:

class Body{
    public int BODYNUM = 4;
}
class Person implements Cloneable{
    public String name;
    public int age;
    public Body body;       //body屬性
    public Person(String name,int age,Body body ) {
        this.name = name;
        this.age = age;
        this.body = body;
    }
    public Person clone() throws CloneNotSupportedException {
        return (Person) super.clone();
    }
}
public class Run{
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person("小明",18,new Body());
        Person p2 =  p1.clone();
        System.out.println(p1.hashCode());
        System.out.println(p2.hashCode());
        System.out.println(p1==p2);
        System.out.println(p1.body==p2.body);
        p1.body.BODYNUM = 5;
        System.out.println(p2.body.BODYNUM);    
    }
}

輸出:

366712642
1829164700
false          //p1==p2
true          //p1.body==p2.body
5            //p2的body屬性的一個值

可以看到,修改了p1的body屬性,p2的 body屬性也修改了。那麼就說明了,其實p1的body跟p2的body實質上還是同一個,因爲克隆的只是引用值而已,引用還是指向內存中同一個區域。
這個時候,Body屬性必須也實現Cloneable接口
例如:

class Body implements Cloneable{
    public int BODYNUM = 4;
    public Body clone() throws CloneNotSupportedException {
        return (Body) super.clone();
    }
}
class Person implements Cloneable{
    public String name;
    public int age;
    public Body body;
    public Person(String name,int age,Body body ) {
        this.name = name;
        this.age = age;
        this.body = body;
    }
    public Person clone() throws CloneNotSupportedException {
        Person person = (Person) super.clone();
        person.body = body.clone();   //可以認爲將包含引用的屬性都要自己拷貝一遍
        return person;
    }
}
public class Run{
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person("小明",18,new Body());
        Person p2 =  p1.clone();
        System.out.println(p1.hashCode());
        System.out.println(p2.hashCode());
        System.out.println(p1==p2);
        System.out.println(p1.body==p2.body);
        p1.body.BODYNUM = 5;
        System.out.println(p2.body.BODYNUM);    
    }
}

輸出:

366712642
1829164700
false
false       //p1的body與p2的body不一樣了
4          //修改p1的body後,p2並未受到修改

這也就是傳說中的深拷貝,即在重寫clone方法中拷貝所有的引用屬性;

2. equals(Object obj)

該方法具有如下特性:

  • 自反性:對於任何非空引用x; x.equals(x)應當返回true;
  • 對稱性:對於任何非空引用x,y;x.equals(y)返回true當且僅當y.equals(x)返回true;
  • 傳遞性:對於任何非空引用 x,y,z,如果x.equals(y)=true,y.equals.(z)=true,那麼x.equals(z)=true
  • 一致性:對於任何非空引用 x,y,調用多次x.equals(y)返回結果應該相同;
  • 對於任何非空引用x,xequals(null)應該返回false;

源碼如下:

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

很多都會重寫該方法。

3. finalize()

是終止函數,JVM在進行垃圾回收的時候首先會調用這個函數,當某個對象被確認爲無用信息的時候,那麼就會釋放該對象的內存,但是不一定有效。
一般人爲不使用該方法。

class Person{
    //重寫了Object類的finalize方法,當Person類被回收的時候首先調用該方法
    public void finalize() throws Throwable{ 
        System.out.println("回收前調用");
    }
}
public class Run {
    public static void main(String[] args) {
        Person p = new Person();
        p = null;
        System.gc();
    }   
}

輸出:

回收前調用

表明gc的時候調用了Person類的finalize方法
但是需要注意,只有p沒有指向的時候,即被認爲是無用信息的時候纔會被回收,如果去掉上面的p=null,那麼還是不會有輸出。

4. getClass()

返回該對象運行時的類。
例如:

public class Run{
    public static void main(String[] args) throws CloneNotSupportedException {
        String a = "a";
        System.out.println(a.getClass());

    }
}

輸出:

class java.lang.String

5. hashCode()

該方法返回對象的hash值,具有如下特點:

  • 同一對象調用多次該方法應該返回相同值
  • 如果兩個對象通過equals方法返回true,那麼調用hashCode方法應該返回相同hash值
  • 不是一定要“兩個對象通過equals方法返回true,那麼調用hashCode方法應該返回相同hash值”,但是通常應該這麼做,提高HashTable的性能

6. notify()

該方法喚醒在此同步監視器上等待的一個線程,如果有多個線程等待,則隨機喚醒一個。

  • 如果在synchronized修飾的同步方法中使用,則可以直接使用該方法,因爲this就是同步監視器
  • 如果在synchronized修飾的同步代碼塊中使用,則使用括號中的同步監視器來調用該方法。

7. notifyAll()

該方法喚醒在此同步監視器上等待的所有的線程。

8. toString()

該方法將任何對象轉換爲字符串類型
返回getClass().getName() + '@' + Integer.toHexString(hashCode())

例如:

public class Run {
    public static void main(String[] args) {
        Run r = new Run();
        System.out.println(r.toString());
        System.out.println(r.toString() instanceof String);
    }   
}

輸出:

hello.Run@15db9742
true

9. wait()

該方法將當天線程進入等待,直到有其他線程喚醒它。

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