Object類概述
java.lang.Object類是Java語言中的根類,即所有類的父類。它中描述的所有方法子類都可以使用。在對象實例化的時候,最終找的父類就是Object。
如果一個類沒有特別指定父類, 那麼默認則繼承自Object類。例如:
public class MyClass /*extends Object*/ {// ...}
根據JDK原始碼及Object類的API文檔,Object類當中包含的方法有11個。今天我們主要學習其中的2個:
public String toString():返回該對象的字符串表示。
public boolean equals(Object obj):指示其他某個對象是否與此對象「相等」。
toString方法
方法摘要
public String toString():返回該對象的字符串表示。
toString方法返回該對象的字符串表示,其實該字符串內容就是對象的類型+@+內存地址值。
由於toString方法返回的結果是內存地址,而在開發中,經常需要按照對象的屬性得到相應的字符串表現形式,因此也需要重寫它。
覆蓋重寫
如果不希望使用toString方法的默認行為,則可以對它進行覆蓋重寫。例如自定義的Person類:
public class Person { private String name; private int age; @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } // 省略構造器與Getter Setter}
在IntelliJ IDEA中,可以點擊Code菜單中的Generate...,也可以使用快捷alt+insert,點擊toString()選項。選擇需要包含的成員變量並確定。如下圖所示:
貼士: 在我們直接使用輸出語句輸出對象名的時候,其實通過該對象調用了其toString()方法。
equals方法
方法摘要
public boolean equals(Object obj):指示其他某個對象是否與此對象「相等」。
調用成員方法equals並指定參數為另一個對象,則可以判斷這兩個對象是否是相同的。這裡的「相同」有默認和自定義兩種方式。
默認地址比較
如果沒有覆蓋重寫equals方法,那麼Object類中默認進行==運算符的對象地址比較,只要不是同一個對象,結果必然為false。
對象內容比較
如果希望進行對象的內容比較,即所有或指定的部分成員變量相同就判定兩個對象相同,則可以覆蓋重寫equals方法。例如:
import java.util.Objects;public class Person {private String name;private int age;@Override public boolean equals(Object o) { // 如果對象地址一樣,則認為相同 if (this == o) return true; // 如果參數為空,或者類型信息不一樣,則認為不同 if (o == null || getClass() != o.getClass()) return false; // 轉換為當前類型 Person person = (Person) o; // 要求基本類型相等,並且將引用類型交給java.util.Objects類的equals靜態方法取用結果 return age == person.age && Objects.equals(name, person.name); }}
這段代碼充分考慮了對象為空、類型一致等問題,但方法內容並不唯一。大多數IDE都可以自動生成equals方法的代碼內容。在IntelliJ IDEA中,可以使用Code菜單中的Generate…選項,也可以使用快捷鍵alt+insert,並選擇equals() and hashCode()進行自動代碼生成。如下圖所示:
tips:Object類當中的hashCode等其他方法,今後學習。
Objects類
Objects類是對象工具類,它裡面的的方法都是用來操作對象的。
equals方法
在剛才IDEA自動重寫equals代碼中,使用到了java.util.Objects類,那麼這個類是什麼呢?
在JDK7添加了一個Objects工具類,它提供了一些方法來操作對象,它由一些靜態的實用方法組成,這些方法是null-save(空指針安全的)或null-tolerant(容忍空指針的),用於計算對象的hashcode、返回對象的字符串表示形式、比較兩個對象。
在比較兩個對象的時候,Object的equals方法容易拋出空指針異常,而Objects類中的equals方法就優化了這個問題。方法如下:
public static boolean equals(Object a, Object b):判斷兩個對象是否相等。
我們可以查看一下源碼,學習一下:
public static boolean equals(Object a, Object b) { return (a == b) || (a != null && a.equals(b));
isNull
static boolean isNull(Object obj) 判斷對象是否為null,如果為null返回true。
Student s1 = null;Student s2 = new Student("蔡徐坤", 22);// static boolean isNull(Object obj) 判斷對象是否為null,如果為null返回trueSystem.out.println(Objects.isNull(s1)); // trueSystem.out.println(Objects.isNull(s2)); // false
Date類
Date概述
java.util.Date`類 表示特定的瞬間,精確到毫秒。
繼續查閱Date類的描述,發現Date擁有多個構造函數,只是部分已經過時,我們重點看以下兩個構造函數
public Date():從運行程序的此時此刻到時間原點經歷的毫秒值,轉換成Date對象,分配Date對象並初始化此對象,以表示分配它的時間(精確到毫秒)。public Date(long date):將指定參數的毫秒值date,轉換成Date對象,分配Date對象並初始化此對象,以表示自從標準基準時間(稱為「曆元(epoch)」,即1970年1月1日00:00:00 GMT)以來的指定毫秒數。
tips: 由於中國處於東八區(GMT+08:00)是比世界協調時間/格林尼治時間(GMT)快8小時的時區,當格林尼治標準時間為0:00時,東八區的標準時間為08:00。
簡單來說:使用無參構造,可以自動設置當前系統時間的毫秒時刻;指定long類型的構造參數,可以自定義毫秒時刻。例如:
import java.util.Date;public class Demo01Date {public static void main(String[] args) { // 創建日期對象,把當前的時間 System.out.println(new Date()); // Tue Jan 16 14:37:35 CST 2020 // 創建日期對象,把當前的毫秒值轉成日期對象 System.out.println(new Date(0L)); // Thu Jan 01 08:00:00 CST 1970 }}
tips:在使用println方法時,會自動調用Date類中的toString方法。Date類對Object類中的toString方法進行了覆蓋重寫,所以結果為指定格式的字符串。
Date常用方法
Date類中的多數方法已經過時,常用的方法有:
public long getTime()把日期對象轉換成對應的時間毫秒值。public void setTime(long time)把方法參數給定的毫秒值設置給日期對象示例代碼
public class DateDemo02 {public static void main(String[] args) { //創建日期對象 Date d = new Date(); //public long getTime():獲取的是日期對象從1970年1月1日 00:00:00到現在的毫秒值 //System.out.println(d.getTime()); //System.out.println(d.getTime() * 1.0 / 1000 / 60 / 60 / 24 / 365 + "年"); //public void setTime(long time):設置時間,給的是毫秒值 //long time = 1000*60*60; long time = System.currentTimeMillis(); d.setTime(time); System.out.println(d); }}
小結:Date表示特定的時間瞬間,我們可以使用Date對象對時間進行操作。