Object是所有類的最終祖先。,可以使用Object類引用任何類型的對象。在Java中,只有基本類型不是對象。
Equals方法
Object類中的equals方法用於檢測一個對象是否等於另外一個對象。在Object類中,這個方法將判斷兩個對象是否具有相同的引用。
但是,我們一般意義上的相等不僅僅是具有相同的引用,如果另個對象的狀態相等,就認為另個對象是相等的。所以,子類要重寫超級類中的equals方法。
Java中,要求equals方法具有下面的特性:
- 自反性,x.equals(x)返回ture。
- 對稱性,x.equals(y),和y.equals(x)返回相同的值。
- 傳遞性,對於任何引用x,y,z,如果x.equals(y)返回true,y.equals(z)返回true,那麼x.equals(z)也要返回true。
- 一致性,如果x和y所引用的對象沒有變化,反覆調用x.equals(y)應該返回同樣的結果。
- 對於任意非Null 參考x,x.euqals(null)應該返回false。
如下例,實現了倆個equals方法:
package com.xujin;import java.util.Arrays;public class Test {public static void main(String[] args) {Employee employee = new Employee("Bod", 5000);Employee staff = employee;Manager manager = new Manager("Bod", 8000, 6000);System.out.println(employee.equals(new Employee("Bod", 5000)));//trueSystem.out.println(employee.equals(staff));//trueSystem.out.println(employee.equals(null));//falseSystem.out.println(manager.equals(new Manager("Bod", 8000, 6000)));//trueSystem.out.println(employee.equals(manager));//falseSystem.out.println(employee instanceof Employee);//trueSystem.out.println(employee instanceof Manager);//falseSystem.out.println(manager instanceof Employee);//true//考察兩個數組是否相同System.out.println(Arrays.equals(new int[]{1,2,3}, new int[]{1,2,3}));//true}}class Employee{public Employee(String name, double salary){this.name = name;this.salary = salary;}public boolean equals(Object otherObject){//如果兩個對象具有相同的引用,返回trueif(this == otherObject) return true;//如果otherObjext是null,返回falseif(otherObject == null) return false;//如果兩個對象所屬的類不相同,返回falseif(this.getClass() != otherObject.getClass()) return false;//此時,兩個對象既不是null,他們所屬的類也相同,都為EmployeeEmployee other = (Employee)otherObject;return name.equals(other.name) && salary == other.salary;}//定義變數private double salary;private String name;}class Manager extends Employee{public Manager(String name, double salary, double bonus){super(name, salary);this.bonus = bonus;}public boolean equals(Object otherObject){if(!super.equals(otherObject))return false;Manager other = (Manager)otherObject;return bonus == other.bonus;}private double bonus;}
HashCode方法散列嗎,是由對象匯出的一個整型值。此方法是有Object定義的,返回該對象的儲存地址。所以,如果有必要,子類要對HashCode方法進行重寫。注意:如果重寫了equals方法,則必須重寫HashCode方法,因為這兩個方法必須一致:如果equals方法返回true,則HashCode方法必須返回相同值。下例中,String類已經重寫了HashCode方法,使用對象的值匯出散列碼,而StringBuilder方法沒有重寫HashCode方法,返回的依然是儲存單元的地址。
package com.xujin;public class Main{public static void main(String...args){String s1 = "Hello,world!";String s2 = new String("Hello,world!");System.out.println(s1.hashCode());//2007142665System.out.println(s2.hashCode());//2007142665StringBuilder sb1 = new StringBuilder("Hello,world!");StringBuilder sb2 = new StringBuilder(s1);System.out.println(sb1.hashCode());//1291383602System.out.println(sb2.hashCode());//1814462232}}
toString方法在Object類中,它用於返回對象所屬類名和散列碼,例如
package com.xujin;public class Main{public static void main(String...args){System.out.println(System.out);//java.io.PrintStream@6102d81c}}
輸出的是一個java.io.PrintStream@6102d81c,這是因為System.out所屬的PrintStream類並沒有覆蓋Object的toString方法。而在大多數情況下,它用於返回表示對象值的字串。絕大多數的toString方法都遵循這個格式: 類名[域值,域值,域值......]如下例:
package com.xujin;public class Main{public static void main(String...args){Employee staff = new Employee("Bob",8000);System.out.println(staff.toString());}}class Employee{public Employee(String name, double salary){this.name = name;this.salary = salary;}public String toString(){return getClass().getName() + "[name = " + name + ", salary = " + salary + "]";}//定義變數private double salary;private String name;}
輸出將是:com.xujin.Employee[name = Bob, salary = 8000.0]其實,只要對象與一個字串通過操作符“+”串連起來,Java編譯就會自動的調用toString方法,以便獲得這個對象的字串描述。