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; } }
publicclass 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方法為什麼不能對整數進行判斷?
*注意這兩種方法都有返回值,呼叫時需要注意
明天學習時間類