Object类
所有类的超类,无论是Java中已存在的类还是我们自定义的类,均默认继承Object类,自然而然,其中的方法也都默认继承拥有,即可以用已存在类或者自定义类的实例对象去访问Object类的方法。
Object类中方法挺多,但在这不一一介绍,只说几个平时常用的方法
toString()方法:返回对象的字符串描述。非常熟悉,因为平时码代码时想查看一个对象都是通过调用toString方法
假设我们定义了一个类Person
class Person{
private String name;
private int id;
public Person(){}
public Person(String name,int id){
this.name = name;
this.id = id;
}
}
当我们在程序中执行下列语句时
Person p1 =new Person(110,"Dream");
System.out.println(p1.toString());
System.out.println(p1);
会发现结果都一样,如下
BasicObject.Person@16d3586
BasicObject.Person@16d3586
明明是一个调用了toString()方法,一个未调用,但是为什么输出结果是一样的呢?
这时候我们就需要去考虑println方法是不是对其中的对象执行了toString方法然后再打印结果?为了验证这种猜测,就需要我们去查看println方法的源码
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
果不其然,其中的valueOf方法果真去调用了Object的toString方法,所以不难理解为什么没有调用toString方法但是打印结果却是一样的。
对于上述的输出结果,其实调用的就是Object的toString方法,源码如下:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
但是对于输出的信息并不是我们想要的去反映该对象的信息,即Object类的toString方法并不能将我们需要的描述对象的字符串转换出来,所以需要我们去重写这个方法,就拿上述的Person类来说,其中的toString方法写成如下形式就能输出符合我们需求的数据格式
public String toString(){
return "Name:"+name+",id:"+id;
}
equals(Object o)方法:默认情况下比较两个对象的内存地址,判断两个对象是否是同一个对象(即是否指向同一个引用)
继续用上述的Person类作为示例
Person p1 =new Person(110,"Dream");
Person p2 =new Person(110,"Dream");
System.out.println(p1.equals(p2));
输出结果是false,因为创建了两个对象p1,p2,虽然两个对象的id和name是一致的,但是内存地址是不同的,所以比较结果是false;此时,如果我们觉得两个人只要id值相同就可以认为这两个人是同一个人,那么此时就需要我们重写equals方法去满足我们的需求
public boolean equals(Object other){
Person p = (Person)other;
return id == p.getId();
}
其中重写equals方法首先最好有如下判断
1.首先判断当前对象和other对象是否是同一个对象,即是否是指向同一个引用,如果是同一个引用则直接返回true,否则继续进行判断
2.判断other对象是否为空,如果为空,直接返回false,否则继续进行判断
3.最终进行上述方法中的id是否相等的判断
hashCode()方法:返回该对象的哈希代码值,可以把哈希代码值理解为对象的内存地址
Java规范:一般重写了equals方法就需要我们重写hashCode方法,因为需要保证如果两个对象相等,那么他们的hashCode值也应该相同