首先,从本质上对这两者进行一下区分:“==”是一种关系运算符,用于比较两变量的值是否相等,其中两变量可以是基本数据类型,也可以是引用数据类型;而equals()属于java.lang.Object类里面的方法,因此只有对象才可以调用该方法,所以equals()只能使用在引用数据类型上 。下面分别给出两者的使用规则:
1.“==”的使用1).如果是用在基本数据类型变量上,比较的是两个变量的值是否相等。
2).如果使用在引用数据类型变量上,比较的是两个引用保存的地址值是否相等。
int num1 = 10; int num2 = 10; System.out.println(num1 == num2); //输出结果为"true" float f1 = 10.0F; System.out.println(num1 == f1); //输出结果为"true" int num = 65; char c = 'A'; System.out.println(c == num); //输出结果为"true"
上述代码段中的三个例子输出结果均为true,例2和3在比较之前进行了自动类型提升。
User u1 = new User("Murphy",22);
User u2 = new User("Murphy",22);
System.out.println(u1 == u2); //输出结果为false
上述代码段中对象u1和u2是两个不同的对象,所以地址值不等。
2.“equals()”的使用作为java.lang.Object类中的方法,它只能用于比较引用数据类型。首先给出Object类中equals()方法的原始定义:
容易看出,在默认情况下(子类没有重写Object类的eauals()情况下),调用此方法,比较的仍然是两个对象的地址值是否相等。也就是仍然相当于“==”运算符应用于引用类型变量的情况。
User u1 = new User("Murphy",22);
User u2 = new User("Murphy",22);
System.out.println(u1 == u2);
System.out.println(u1.equals(u2)); //u1和u2的地址值不同
User u3 = u1;
System.out.println(u1 == u3); //此时u1与u3保存的地址值是一样的
上述代码中,对象u1和u2的的地址值不等,u3和u1存储的是同一片地址空间。运行结果如下图所示
可见,如果equals()方法没有被子类重写的话,其所用和“==”相同,也进一步验证了equals()比较的是两对象的地址值。
但是像String、Date、File、包装类等类,都重写了Object类的equals(),重写的目的是比较两个对象的实体内容是否相等。同样,在开发中,对于自定义的类,往往也需要比较两个对象的实体内容是否相等。此时就要重写Object类中的equals方法。下面我们在User类中对equals()进行重写,用于比较User类中的属性name 和age是否都相等,重写的equals()为:
public boolean equals(Object obj){
if(this == obj){
return true;
}
if(obj instanceof User){
User user = (User)obj;
return (this.age == user.age && this.name.equals(user.name));
} else{
return false;
}
}
重写之后重新运行上述代码段,运行结果如下:
总结:对于equals()的使用,具体要看子类中有没有重写过Object类中的equals()。因为String等类的方法是被重写过的,而且String类在日常开发中用的比较多,久而久之,就会使很多人形成了equals是比较值的错误观点。



