今天遇到一个比较细节的bug,稍微有点基础的都知道 == 和 equals 的用法,前者用于比较基础数据类型值是否相等,当用于引用类型的时候,一般比较的都是引用地址,因此我们在比较两个对象是否相等时就用后者。然而。。。

先来看一段代码:

Integer n1 = new Integer(21);
Integer n2 = new Integer(21);
System.out.println(n1 == n2);
System.out.println(n1.equals(n2));

不难知道。前者比较的引用,返回false,后者比较的内容,返回true;

下面,我们自定义一个Student类:

class Student {
	private String name;
	private int age;
	
	public Student(String name,int age) {
		this.name = name;
		this.age = age;
	}
}

省略掉了setter和getter,然后我们再来new两个对象比较一下:

Student s1 = new Student("Big",21);
Student s2 = new Student("Big",21);
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));

你能猜到打印的结果吗?两个都是false!这就很费解了,为什么equals不好使了呢?这是因为:

因为equals()方法默认行为是比较引用,因此在新类中要自己重写equals()方法,否则不可能表现出我们希望的行为。 ——《Thinking in Java》3.7.1

OK,到这里我们就发现了原因了,我们在Student类中添加一个equals方法:

    public boolean equals(Student s) {
        if (s != null && this.name.equals(s.name) && this.age == s.age)
            return true;
        return false;
    }

至此,问题解决,s1.equals(s2) 会返回我们期望的结果。虽然,问题很小,但是不了解equals方法的默认行为的话,这个bug还是很难发现的。