标签:其他 获得 没有 end rri 特性 bool etag 内容
Object类中的equals方是用来判断一个对象等于另一个对象,至于这个等于的条件需要,比如说,String类的equals相等的条件就是字符串的内容必须相同,equals方法返回的值才为true。所以在我们在自己定义的类中,equals的重写是常见的!这里主要展示equals的特性和equals的正确写法,至于equals方法具体的含义这里不介绍!
在这介绍其他的,我们先来看看正确的写法
public class Animal {
private String name = null;
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj == null) {
return false;
}
if(this.getClass() != obj.getClass()) {
return false;
}
Animal animal = (Animal) obj;
//return this.name.equals(animal.name);
//这个方法只在JDK7及其以后才有的
//这个方法能够保证两个name其中只有一个为null的话,返回的false
//如果两个都为null的话,返回的是true
//如果两个都不为null的话,具体看情况
return Objects.equals(this.name, animal.name);
}
}
从上面的代码中我们看到是,Animal类的equals方法判断的相等条件是name是否为相同。说实话,判断的条件非常的简单,但是我们的代码写的非常复杂。可能有人会这样写的:
public boolean equals(Object obj) {
if(! (obj instanceof Animal)) {
return false;
}
Animal animal = (Animal) obj;
return this.name.equals(animal.name);
}
实际上,上面的代码是有很大的问题,至于有什么问题,待会再说!这里我们来解释一下正确equals方法写的代码:
那么这种写法有好处呢,等我把在列出一个类的代码再说吧!
public class Dog extends Animal{
private int age = 0;
public Dog(String name, int age) {
super(name);
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
if(!super.equals(obj)) {
return false;
}
Dog dog = (Dog) obj;
return this.age == dog.age;
}
}
我们发现Dog类继承于Animal类,并且重写了父类的equals方法。在Dog类中equals方法,我们先来判断了这两个对象是否是相等的,其次再比较了age是否相同的。其中先调用了父类的equals来判断,再来判断子类本身的条件,这种方法有几个好处:
上面留了一些伏笔,这里将详细的解释,但是在解释之前,我们先来看看equals方法的特性:
针对这些特性,我们拿一个特性来解释为什么使用instanceof关键字来进行判断有很大的问题。
假设,记住这里是假设:如果Animal类的equals方法和Dog类的equals方法使用的是instanceof关键字来判断的,也就是下面的代码:
@Override
public boolean equals(Object obj) {
if(!(obj instanceof Animal)) {
return false;
}
Animal animal = (Animal) obj;
return Objects.equals(this.name, animal.name);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Dog)) {
return false;
}
Dog dog = (Dog) obj;
return this.age == dog.age;
}
public static void main(String[] args) {
Animal a1 = new Animal("pby");
Dog d1 = new Dog("pby", 21);
System.out.println(a1.equals(d1));
System.out.println(d1.equals(a1));
}
我们可以看到的是第一个结果返回的true,但是第二个返回的false。这个就有问题了,不符合equals方法的对称性。
我们来分析一下,当a1.equals(d1)时,调用的Animal类中的equals方法,这个方法对name进行判断,首先d1 instanceof Animal 肯定为true,因为Dog类是Animal的子类,所以if条件没有屏蔽掉d1,由于两个对象的name是相同的,所以返回值是true,但是真正的结果是false,因为他们不属于同一个类!至于第二个为什么是false,这里将不在解释了!
然后我们回来看正确写法,this.getClass == obj.getClass这个判断就能够将我们的d1屏蔽掉!
标签:其他 获得 没有 end rri 特性 bool etag 内容
原文地址:http://www.cnblogs.com/Stay-Hungry-Stay-Foolish/p/7854905.html