淺談Java Object

Java中,全部的類都繼承自Object類,所以萬物皆對象?也沒錯!java

那有人會問,個人子類繼承的是父類不是Object,怎麼說?面試

若是一個類沒用顯示的繼承某一個類,那麼他就會隱式的繼承 Object多線程

接下來講重點:我在進這家公司面試的時候問道,「Object類包含了哪些方法?」,猶記得當時一臉懵逼的樣子,倒不是說這道題多難,而是那時候弟弟剛大四,雖然是老師直接推薦過去的,但緊張呀。並且還有一些擴展問題,今天就統一總結一下。編輯器

  1. protected Object clone() throws CloneNotSupportedException 建立並返回對象的副本(拷貝)ide

    《阿里巴巴Java開發手冊》建議:慎用Objectclone()方法來拷貝對象,由於Objectclone()方法默認是淺拷貝,即拷貝對象在內存中的地址的引用。若是須要深拷貝,須要重寫clone()方法。spa

    即:插件

    x.clone() != x;
    x.clone().getClass() == x.getcalss();
    x.clone.equals(x); // true

    若是對象的類不支持Cloneable接口,重寫clone()方法則會報此異常。Object類自己並不實現接口Cloneable ,所以在類別爲Object的對象上調用clone()方法將致使運行時拋出異常.線程

  2. public String toString() 返回此對象的字符串表示形式。 《阿里巴巴 Java 開發手冊》強制規定:POJO 類必須重寫 toString 方法;好比:指針

    public class QueryParamInfo {
        private Long startTime;
        private Long endTime;
        private String operator;
        private Integer currentPage;
        private Integer size;
    
        @Override
        public String toString() {
            return "QueryParamInfo{" +
                    "startTime=" + startTime +
                    ", endTime=" + endTime +
                    ", operator='" + operator + '\'' +
                    ", currentPage=" + currentPage +
                    ", size=" + size +
                    '}';
        }
    }

    這些代碼都是插件或者編輯器能夠快捷生成的,不用懼怕,要養成習慣。那好處是什麼呢?很簡單,方便在拋出異常時調用POJOtoString()打印其屬性值,便於排查問題。code

    POJO(Plain Ordinary Java Object)指簡單的 Java 對象,也就是普通的 JavaBeans,包含一些成員變量及其 getter / setter ,沒有業務邏輯。有時叫作 VO (value - object),有時叫作 DAO (Data Transform Object)。

  3. public final Class<?> getClass() 返回Object運行時類。 在運行時能夠獲取對象對應類的信息,詳見反射.

    A a = new A();
    Class b = a.getClass();
    System.out.pringtln(b.getName()); // 輸出A
  4. public int hashCode() 返回對象的哈希值。 hashCode()是一個native方法,返回值是整形。該方法將對象在內存中的地址做爲哈希碼返回,能夠保證不一樣對象的返回值不一樣。 hashCode一般在哈希表中起做用,好比hashMap.

    native方法顧名思義就是本地方法,不一樣平臺上的方法不一樣,有JVM調用實現。好比Thread中的start()方法其實就是調用nativestart0().本身能夠在IDE上點進代碼看一下。

  5. protected void finalize() throws Throwable 當垃圾回收機制肯定該對象再也不被調用時,垃圾回收器會調用此方法. 此方法在JDK9中標註deprecated,因此很少說。

  6. public boolean equals(Object obj) 判斷兩個對象是否相等

    • == : 它的做用是判斷兩個對象的地址是否是相等。即,判斷兩個對象是否是同一個對象(基本數據類型==比較的是值,引用數據類型==比較的是內存地址)。
    • equals()也是判斷兩個對象是否相等,它有兩種使用狀況:
      1. 類沒有覆蓋 equals() 方法。則經過 equals() 比較該類的兩個對象時,等價於經過「==」比較這兩個對象。
      2. 類覆蓋了equals()方法。通常,咱們都覆蓋equals()方法來比較兩個對象的內容是否相等;若它們的內容相等,則返回 true (即,認爲這兩個對象相等)。

    舉例:

    public class test1 {
        public static void main(String[] args) {
            String a = new String("ab"); // a 爲一個引用
            String b = new String("ab"); // b爲另外一個引用,對象的內容同樣
            String aa = "ab"; // 放在常量池中
            String bb = "ab"; // 從常量池中查找
            if (aa == bb) // true
                System.out.println("aa==bb");
            if (a == b) // false,非同一對象
                System.out.println("a==b");
            if (a.equals(b)) // true
                System.out.println("aEQb");
            if (42 == 42.0) { // true
                System.out.println("true");
            }
        }
    }
    • String 中的 equals 方法是被重寫過的,由於 objectequals 方法是比較的對象的內存地址,而 Stringequals 方法比較的是對象的值。
    • 當建立 String 類型的對象時,虛擬機會在常量池中查找有沒有已經存在的值和要建立的值相同的對象,若是有就把它賦給當前引用。若是沒有就在常量池中從新建立一個 String 對象。

    《阿里巴巴 Java 開發手冊》上強調:因爲 Objectequals 方法容易拋出空指針異常,因此應該使用常量或者肯定不爲 null 的對象來調用 equals

    String a = null;
    "test".equals(a); //false
    a.equals("test"); // 拋出異常
    
    // 推薦用法
    Objects.equals(a,"test"); //false
    // 具體緣由和使用看java.util.Objects#equals的源碼
  7. wait()notify()notifyAll() 這三個放在一塊兒說是由於,你們都熟悉並且使用場景一致。就是在多線程加同步鎖時等待、通知喚醒方法。沒錯他們不是Thread中的方法是Object的。

總結:

雖然終極父類是Object,但那8個基本類型不在其列。 本篇文章主要就是讓你們對Object的印象更加深入一點,並拓展了一些知識和本身的理解。若有不當之處,望批評指正。對你們有幫助的話點個贊,Wink~~

相關文章
相關標籤/搜索