java基礎之 超類Object

1、概述:java

      Object類是全部Java類的祖先。每一個類都使用 Object 做爲超類。全部對象(包括數組)都實現這個類的方法。
      在不明確給出超類的狀況下,Java會自動把Object做爲要定義類的超類。
      可使用類型爲Object的變量指向任意類型的對象。
      Object類是Java中惟一沒有父類的類
      Object類有一個默認構造方法pubilc Object(),在構造子類實例時,都會先調用這個默認構造方法。

 2、API預覽
程序員

    Object()
    默認構造方法
數組

    clone()
    建立並返回此對象的一個副本。
    equals(Object obj)
    指示某個其餘對象是否與此對象「相等」。
    finalize()
    當垃圾回收器肯定不存在對該對象的更多引用時,由對象的垃圾回收器調用此方法。
    getClass()
    返回一個對象的運行時類。
    hashCode()
    返回該對象的哈希碼值。
    notify()
    喚醒在此對象監視器上等待的單個線程。
    notifyAll()
    喚醒在此對象監視器上等待的全部線程。
    toString()
    返回該對象的字符串表示。
    wait()
    致使當前的線程等待,直到其餘線程調用此對象的 notify() 方法或 notifyAll() 方法。
    wait(long timeout)
    致使當前的線程等待,直到其餘線程調用此對象的 notify() 方法或 notifyAll() 方法,或者超過指定的時間量。
    wait(long timeout, int nanos)
    致使當前的線程等待,直到其餘線程調用此對象的 notify() 方法或 notifyAll() 方法,或者其餘某個線程中斷當前線程,或者已超過某個實際時間量。
dom

3、方法使用說明
equals() (判斷兩個對象是否相等)
ide

 1)基本數據類型,也稱原始數據類型。byte,short,char,int,long,float,double,boolean   他們之間的比較,用雙等號(==),比較的是他們的值。 函數

 2)複合數據類型(類)   當他們用(==)進行比較的時候,比較的是他們在內存中的存放地址,因此,除非是同一個new出來的對象,他們的比較後的結果爲true,不然比較後結果爲false。equals()這個方法的初始行爲是比較對象的內存地址,但在一些類庫當中這個方法被覆蓋掉了,如String,Integer,Date在這些類當中equals有其自身的實現,而再也不是比較類在堆內存中的存放地址了。工具

例:this

        People p=new People();
        p.setName("234");
        
        People p2=new People();
        p2.setName("234");
        
        System.out.println(p.equals(p2)); //false
        System.out.println(p==p2);//false

        String s="123";
        String s1=new String("123");
        String s2=new String("123");
        
       
        System.out.println(s==s1);//false
        System.out.println(s.equals(s1));//true
        System.out.println(s1==s2);//false
        System.out.println(s1.equals(s2));//true
View Code

Java語言規範要求equals方法具備下面的特色: spa

  • 自反性:對於任何非空引用值 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,屢次調用 x.equals(y) 始終返回 true 或始終返回 false,前提是對象上 equals 比較中所用的信息沒有被修改。 對於任何非空引用值 x,x.equals(null) 都應返回 false

 hashCode()( 返回該對象的哈希碼值)

  hashCode 的常規協定是(重寫equals()時,必須重hashcode()並保證此協定):線程

  • 若是調用equals方法獲得的結果爲true,則兩個對象的hashcode值一定相等
  • 若是equals方法獲得的結果爲false,則兩個對象的hashcode值不必定不一樣
  • 若是兩個對象的hashcode值不等,則equals方法獲得的結果一定爲false
  • 若是兩個對象的hashcode值相等,則equals方法獲得的結果未知

咱們會有這樣的協定,舉個例子:

 

class User {
    String name;
    public User(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public boolean equals(Object o) {
        User u = (User) o;
        return name.equals(u.getName());
    }
}

 

 public static void main(String[] args) {
        List<User> list = new ArrayList<User>();
        list.add(new User("lily"));
        Map<User, String> map = new HashMap<User, String>();
        map.put(new User("lily"), "11");

        System.out.println(list.contains(new User("lily"))); //true
        System.out.println(map.containsKey(new User("lily")));//false
    }

緣由就不寫了 。。本身領悟叭

 

toString()(返回該對象的字符串表示)

Object類中的toString()方法會打印出類名和對象的內存位置。幾乎每一個類都會覆蓋該方法,以便打印對該對象當前狀態的表示。大多數(非所有)toString()方法都遵循以下格式:類名[字段名=值,字段名=值...],固然,子類應該定義本身的toString()方法。該方法是很是重要的調試工具,不少標準類庫中的類都定義了toString()方法,以便程序員得到有用的調試信息

clone()(建立並返回此對象的一個副本

克隆的分類:
  (1)淺克隆(shallow clone),淺拷貝是指拷貝對象時僅僅拷貝對象自己和對象中的基本變量,而不拷貝對象包含的引用指向的對象。
  (2)深克隆(deep clone),深拷貝不只拷貝對象自己,並且拷貝對象包含的引用指向的全部對象。
克隆的實現:
  1. 讓該類實現java.lang.Cloneable接口;
  2. 重寫(override)Object類的clone()方法。
該方法是淺克隆,若是須要實現深克隆,則須要重寫clone方法)
爲何克隆是淺拷貝:
1) 效率和簡單性,簡單的copy一個對象在堆上的的內存比遍歷一個對象網而後內存深copy明顯效率高而且簡單。
2 ) 不給別的類強加意義。若是A實現了Cloneable,同時有一個引用指向B,若是直接複製內存進行深copy的話,意味着B在乎義上也是支持Clone的,可是這個是在使用B的A中作的,B甚至都不知道。破壞了B原有的接口。
3) 有可能破壞語義。若是A實現了Cloneable,同時有一個引用指向B,該B實現爲單例模式,若是直接複製內存進行深copy的話,破壞了B的單例模式。
4) 方便且更靈活,若是A引用一個不可變對象,則內存deep copy是一種浪費。Shadow copy給了程序員更好的靈活性。
克隆知足的條件:
clone()方法將對象複製了一份並返還給調用者。所謂「複製」的含義與clone()方法是怎麼實現的。通常而言,clone()方法知足如下的描述:
(1)對任何的對象x,都有: x.clone()!=x。換言之,克隆對象與原對象不是同一個對象
(2)對任何的對象x,都有: x.clone().getClass() == x.getClass(),換言之,克隆對象與原對象的類型同樣。
(3)若是對象x的equals()方法定義其恰當的話,那麼 x.clone().equals(x)應當成立的。
在JAVA語言的API中,凡是提供了clone()方法的類,都知足上面的這些條件。JAVA語言的設計師在設計本身的clone()方法時,也應當遵照着三個條件。通常來講,上面的三個條件中的前兩個是必需的,而第三個是可選的。

建立對象的幾種方式:

  1)new
     new操做符的本意是分配內存。程序執行到new操做符時, 首先去看new操做符後面的類型,由於知道了類型,才能知道要分配多大的內存空間。 分配完內存以後,再調用構造函數,填充對象的各個域,這一步叫作對象的初始化,構造方法返回後,一個對象建立完畢
  2)反射
   a: Student stu = (Student)Class.forName("根路徑.Student").newInstance()
   b: Student stu = Student.class.newInstance()
區別:
> Class類的newInstance只能觸發無參數的構造方法建立對象,而構造器類的newInstance能觸發有參數或者任意參數的構造方法來建立對象。
> Class類的newInstance須要其構造方法是共有的或者對調用方法可見的,而構造器類的newInstance能夠在特定環境下調用私有構造方法來建立對象。
> Class類的newInstance拋出類構造函數的異常,而構造器類的newInstance包裝了一個InvocationTargetException異常。
  3)clone
       先分配內存,將原來對象內存裏的內容copy一份。不會調用構造方法
  4)反序列化
 
 wait() & notify()
wait():
做用於持有該對象鎖的當前線程,使線程從運行態,進入到等待阻塞狀態,釋放對象鎖,釋放cpu控制權,調用該方法的前提是得到對象鎖
notify()/notifyAll:
做用於持有該對象鎖的線程(其中一個/所有),使線程從等待阻塞狀態,進入到鎖池阻塞狀態,調用該方法的前提是得到對象鎖
舉個栗子
生產者消費者模型
倉庫
class Store {
    public static List<String> store = new ArrayList<String>();
    public static int limitSize = 5;
}
View Code

生產者

class Producer implements Runnable {
    @Override
    public void run() {
        while (true) {
            synchronized (Store.store) {
                while (Store.store.size() == Store.limitSize) {
                    try {
                        Store.store.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("建立一個商品");
                Store.store.add(UUID.randomUUID().toString());
                Store.store.notifyAll();
            }
        }
    }
}
View Code

消費者

class Consumer implements Runnable {
    @Override
    public void run() {
        while (true) {
            synchronized (Store.store) {
                while (Store.store.size() == 0) {
                    try {
                        Store.store.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("消費一個商品");
                Store.store.remove(0);
                Store.store.notifyAll();
            }
        }
    }
}
View Code

啓動生產者,消費者

public static void main(String[] args) {
        Thread producer = new Thread(new Producer());
        Thread consumer = new Thread(new Consumer());
        producer.start();
        consumer.start();
    }
View Code
相關文章
相關標籤/搜索