Object是所有类的父类,具备所有对象都能用的共性内容,下面介绍下常用的四种方法。
1 boolean equals(Object obj)
顾名思义,这是比较对象是否相等的方法(向上转型)。大家周知道,”==“是用来比较两个对象地址是否相同的方法,那么equals是比较地址还是内容呢?我们通过Object源码来分析下。
class Object{
public boolean equals (Object obj){
return(this==obj);
}
}
通过源码可以知道,Object类本质上也是通过”==“来比较,比较的也是地址。所以,通过如下代码,我们可以清楚知道main函数中均返回情况。
class Car{
int battery;
car(int bat){this.battery=bat;}
}
class Dog{
int age;
Dog(int age){this.age=age;}
}
public static void main(){
Car c1=new Car(10);
Car c2=new Car(10);
Dog d1=new Dog(10);
System.out.println(c1==c2);//false
System.out.println(c1.equals(c2));//false
}
所以,按Object类中的equals()方法,其本质和”==“相同,有种鸡肋的感觉。若想只比较对象内容是否相同,需要其子类对equals方法重写。String 、Math、还有Integer、Double等就进行了重写,所以equals比较的就是内容,也可以自己重写。
public boolean equals(Object obj){
Car c=(Car)obj;
return this.battery==c.battery;
}
system.out.println(c1.equals(c2))//true
2 public native int hasCode()
关键字native表示本地方法,可以理解为java调用非java语言的接口,比如java需要与底层如os或硬件交换信息时,就可以使用native方法。hasCode方法返回对象的哈希码值,先给两个例子看下。
system.out.println(c1);//输出:Car@32ed11,@后面就是对象转换的hash值
system.out.println(Integer.toHexString.(c1.hasCode()));//输出:32ed11;hascode返回十进制数,需要转换成十六进制
在java语言里,基本上重写equals方法后,就有必要重写hasCode()方法,为什么呢?
从java判断两个对象是否相等的规则说起,在java的集合中,存在两个规范:
规范1:若重写equals(Object obj)方法,有必要重写hashcode()方法,确保通过equals(Object obj)方法判断结果为true的两个对象具备相等的hashcode()返回值。说得简单点就是:“如果两个对象相同,那么他们的hashcode应该 相等”。不过请注意:这个只是规范,如果你非要写一个类让equals(Object obj)返回true而hashcode()返回两个不相等的值,编译和运行都是不会报错的。不过这样违反了Java规范,程序也就埋下了BUG。
规范2:如果equals(Object obj)返回false,即两个对象“不相同”,并不要求对这两个对象调用hashcode()方法得到两个不相同的数。说的简单点就是:“如果两个对象不相同,他们的hashcode可能相同”。
根据这两个规范,可以得到如下推论:
1> 如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等。
2> 如果两个对象不equals,他们的hashcode有可能相等。
3> 如果两个对象hashcode相等,他们不一定equals。
4> 如果两个对象hashcode不相等,他们一定不equals。
一般来说,如果你要把一个类的对象放入容器中,那么通常要为其重写equals()方法,让他们比较内容而不是地址值,要放到有序容器中,需要重写compareTo()方法;特别地,如果要把你的类的对象放入散列(hashMap,hashSet)中,那么还要重写hashCode()方法。
记住String对象的三种比较方式:
==内存比较:直接对比两个引用所指向的内存值,精确简洁直接明了。
equals字符串值比较:比较两个引用所指对象字面值是否相等。
hashCode字符串数值化比较:将字符串数值化。两个引用的hashCode相同,不保证内存一定相同,不保证字面值一定相同。
3 class<?>getClass()
方法
反射用,每个Class,都含有getClass方法,用来返回字节码文件对象(Car.class)。而程序运行后,先装载Car.Class字节码文件,然后在对内存中产生Car.Class字节码对象,然后用该字节码对象生成Car对象,而且这些Car对象的地址都是相同的,因为都是基于字节码文件对象地址产生的(引用)。
class cla1=c1.getClass();
class cla2=c2.getClass();
System.out.println(c1==c2);//true,
4 String toString()
方法
该方法用来返回对象字符串。
system.out.println(c1);
system.out.println(c1.toString());//两者效果是相同的