Object类是Java中所有类的始祖,Java中的每一个类都是由它扩展而来,但是并不需要明确写出要继承它。根据前面讲的多态,这就意味着所有的类都可以使用Object类去引用。
这里说明一下Object类中的方法
Object类总共包括11个方法
分别是:
protected Object clone();
boolean equals(Object obj);
protected void finalize();
Class> getClass();
int hashCode();
void notify();
void notifyAll();
String toString();
void wait();
void wait(long timeout);
void wait(long timeout,int nanos);
其中下面要介绍和使用equals、hashCode、toString。
equals方法在Object类中将判断两个对象是否具有相同的引用。而实际应用时一般是重新覆盖此方法的。
而一般重定义时建议按照如下顺序重写:
1)显式参数命名为otherObject,稍后需要将它转换成另一个叫other的变量
2)检测this与otherObject是否引用同一个对象
3)检测otherObject是否为null,如果为null,返回false。
4)比较this与otherObject是否属于同一个类。如果equals的语义在每个子类中有所改变,就使用getClass检测
5)将otherObject转换为相应的类类型变量。
6)对所有需要比较的域进行比较,使用==比较基本类型域,使用equals比较对象域。如果所有的都匹配,返回true,否则返回false。
hashCode(散列码)方法返回一个由对象导出的整数值-是没有规律的。
字符串(String)中的hashCode方法是根据字符串的内容导出的。(StringBuilder并不是字符串类,所以其散列码是默认的)
Object类的hashCode方法是返回对象存储地址。
通常如果定义一个类要覆盖散列码的方法可以调用Objects类中的hash方法,这个方法接受任意多个参数,其返回值的这多个参数调用对应hashCode方法的和。例如 return Objects.hash(name,salary,hireDay);
如果存在数组类型的域,那么可以使用静态的Arrays.hashCode方法计算一个散列码,这个散列码由数组元素的散列码组成。
toString方法,用于返回表示对象值的字符串
绝大多数的toString方法遵循以下原则:
类的名字,随后是一对方括号括起来的域值。
Object类定义的toString方法用来输出打印对象所属类名和散列码。
注意数组类没有覆盖Object类的toString方法,因此要查看数组中元素的值,可以使用Arrays.toString(数组名)。
代码示例:
package Equal;
import java.time.*;
import java.util.Objects;
public class EqualTest {
public static void main(String[] args) {
Employee alice1=new Employee("Alice Adams",75000,1987,12,15);
Employee alice2=alice1;
Employee alice3=new Employee("Alice Adams",75000,1987,12,15);
Employee bob=new Employee("Bob Brandson",50000,1989,10,1);
System.out.println("alice1==alice2:"+(alice1==alice2));
System.out.println("alice1==alice3:"+(alice1==alice3));
System.out.println("alice1.equals(alice3):"+(alice1.equals(alice3)));
System.out.println("alice1.equals(bob):"+(alice1.equals(bob)));
System.out.println("bob.toString():"+bob);
Manager carl=new Manager("Carl Cracker",80000,1987,12,15);
Manager boss=new Manager("Carl Cracker",80000,1987,12,15);
boss.setBonus(5000);
System.out.println("boss.toString():"+boss);
System.out.println("carl.equals(boss):"+(carl.equals(boss)));
System.out.println("alice1.hashCode():"+alice1.hashCode());
System.out.println("alice3.hashCode():"+alice3.hashCode());
System.out.println("bob.hashCode():"+bob.hashCode());
System.out.println("carl.hashCode():"+carl.hashCode());
}
}
class Employee{
private String name;
private double salary;
private LocalDate hireDay;
public Employee(String name,double salary,int year,int month,int day) {
this.name=name;
this.salary=salary;
hireDay=LocalDate.of(year, month, day);
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
public LocalDate getHireDay() {
return hireDay;
}
public void raiseSalary(double byPercent) {
double raise=salary*byPercent/100;
salary+=raise;
}
public boolean equals(Object otherObject) {
if(this==otherObject) {
return true;
}
if(otherObject==null) {
return false;
}
if(getClass() != otherObject.getClass()) {
return false;
}
Employee other=(Employee)otherObject;
return Objects.equals(name, other.name) && salary==other.salary && Objects.equals(hireDay, other.hireDay);
}
public int hashCode() {
return Objects.hash(name,salary,hireDay);
}
public String toString() {
return getClass().getName() +"[name="+name+",salary="+salary+",hireDay="+hireDay+"]";
}
}
class Manager extends Employee{
private double bonus;
public Manager(String name, double salary, int year, int month, int day) {
super(name, salary, year, month, day);
bonus=0;
}
public double getSalary() {
return super.getSalary()+bonus;
}
public void setBonus(double bonus) {
this.bonus=bonus;
}
public boolean equals(Object otherObject) {
if(!super.equals(otherObject)) {
return false;
}
Manager other=(Manager)otherObject;
return bonus==other.bonus;
}
public int hashCode() {
return super.hashCode()+17*new Double(bonus).hashCode();
}
public String toString() {
return super.toString()+"[bonus="+bonus+"]";
}
}
运行结果: