1. 程式人生 > 實用技巧 >Java日誌第23天 2020.7.28

Java日誌第23天 2020.7.28

Object類

java.lang.Object類是類層次結構的頂層,每個類都是用Object類作為父類。

所有物件(包括陣列)都可以實現這個類中的方法。

1.toString類

String toString() 返回該物件的字串表示。

直接列印物件的名字,其實就是呼叫物件的toString方法。

public class People {
    private String name;
    private int age;

    public People() {
    }

    public People(String name, int age) {
        
this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }

public
class DemoMain { public static void main(String[] args) { People p = new People("Gazikel",20); /* People類繼承Object類,所以可以使用Object類中的方法 */ String s = p.toString(); System.out.println(s); //直接列印物件的名字,其實就是呼叫toString方法 System.out.println(p); } }

結果如下:

列印物件的地址值沒有任何的意義,所有需要在類中覆蓋重寫Object類中的toString方法。

Alt+Insert可以自動覆蓋重寫這種方法

  /*
    重寫toString方法
    列印該類的屬性
     */

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

列印結果如下:

所以我們可以通過輸出語句來進行判斷某個類是否進行了toString 方法的覆蓋重寫。

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

public class DemoMain {
    public static void main(String[] args) {
        //任意數
        Random r = new Random();
        System.out.println(r);
        System.out.println("============");
        //輸入
        Scanner sc = new Scanner(System.in);
        System.out.println(sc);
        System.out.println("============");

        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        System.out.println(list);
    }
}

結果如下:

java.util.Random@74a14482
============
java.util.Scanner[delimiters=\p{javaWhitespace}+][position=0][match valid=false][need input=false][source closed=false][skipped=false][group separator=\,][decimal separator=\.][positive prefix=][negative prefix=\Q-\E][positive suffix=][negative suffix=][NaN string=\Q�\E][infinity string=\Q∞\E]
============
[1, 2]

可以看到,Random類沒有重寫toString方法,而Scanner和ArrayList輸出結果不是地址值,故它們重寫了toString方法。

2.equals方法

boolean equals(Object obj) 指示其他某個物件是否與此物件相等

equals原始碼為:

public boolean equals(Object obj){

  return (this == obj);

}

返回值型別是一個布林型別,所以返回true或false

當是基本資料型別比較,則比較它們的大小

當是引用資料型別比較,則比較它們的地址值

public class DemoMain {
    public static void main(String[] args) {
        People p1 = new People("迪麗熱巴",20);
        People p2 = new People("古力娜扎",21);

        System.out.println(p1.equals(p2));//false

        p1 = p2;//將p2地址賦給p1

        System.out.println(p1.equals(p2));//true
    }
}

equals方法只能比較兩個物件的地址值,這也是沒有意義的,所以我們也要覆蓋重寫equals方法。有一個問題,將Object類向下轉型。

 @Override
    public boolean equals(Object obj) {
        People p =(People) obj;
        boolean b = (this.name.equals(p.name)) && (this.age == p.age);
        return b;
    }

當如果equals的引數不是重寫方法中強制轉換的引數時,就會報錯。為了避免這種錯誤,就需要增加一個if語句來進行判斷是否可以進行向下轉型。

另外,我們還可以增加if語句分別判斷引數是否等於null和本身,直接返回一個值,提升程式的效率。

上述所說的程式碼,不需要我們寫,Alt+Insert會自動生成重寫的程式碼。

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

這裡的getClass() != o.getClass() 是利用反射技術來判斷是否可以向下轉型,相當於 o instanceof People。

Objects類的equals方法

因為null是不能呼叫方法的。如果使用Object類中的equals方法,並將引數列表中的引數定義為空,則編譯器就會丟擲空指標異常。

public class DemoMain {
    public static void main(String[] args) {
        String s1 = null;
        String s2 = "abc";

        //boolean b = s1.equals(s2);報錯
        boolean b = Objects.equals(s1, s2);
        System.out.println(b);

    }
}

結果如下:

問題:equals方法為什麼不能對整數進行判斷?

*注意這兩種方法都有返回值,呼叫時需要注意

明天學習時間類