在看下面文章时希望你理解以下概念:
任何一个变量都在内存中,该变量可以储存数据,同时该变量也有其自身的地址
==
相信很多朋友在学习java时听到过一句话,
“两个对象作==比较时,比较的是地址
做equals比较时,比较的是值“
但其实我想说,很多人对这句话理解都错了。
两个对象做==比较时,比较的是他们的地址吗?
不
当两个对象做==比较时,比较的是这两个对象中储存的值。
只不过java中的许多对象都是引用对象类型,而引用对象类型储存的值,就是一块内存空间的地址值。
记住这句话:
java中的引用对象类型的变量,所储存的是一块内存空间的地址值。
而为什么我们输出的时候,难道不应该输出,他们储存的内容,即这些地址值。为什么我们输出的是其他东西呢(例如字符串,数字,等非地址内容。内存地址值输出是0x111这种形式的)
那是因为,java中所有对象都是Object对象的子类,而他们都重写了toString方法,输出一个对象时,其实是输出该对象的toString方法。
举个简单的例子:
String a = "123";
String b = "123";
System.out.println(a==b);
结果是什么?
是true
我们来一句句解析这段代码:
String a
创建一个String类型的变量,命名为a
“123”
内存地址中静态储存区中有一块内存块,这个内存块储存着123,它的地址是0x111
String a = "123"
将赋值号右边的值赋给左边:
所以a储存的就是 0x111
同理b
验证
int i = 1;
int j = 1;
System.out.println(i==j);
结果是true
equals
equals方法其实分好多种情况,
因为
所有类都继承于Object类,
Object中equals的定义是这样的:
public boolean equals(Object obj) {
return (this == obj);
}
所以在Object中==和equals是没有任何区别的。
而如果你自定义一个类User
class User{
int id;
String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
然后比较两个user对象:
User u1 = new User(111,"han");
User u2 = new User(111,"han");
System.out.println(u1.equals(u2));//false
得出的时false,因为你的类User继承于Object类,使用你的user的equals比较时其实是比较的
this == obj
即如果自定义对象不重写equals方法的话,和==比较是没有区别的。
而如果重写了equals方法,就像 String 类等,就按照equals中的规则比较(比较特定内容)
在我看来equals就是为我们提供了一个可自定义比较规则的通道。不用非要用==比较了。
equals
public boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。
equals 方法在非空对象引用上实现相等关系:
- 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
- 对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
- 传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
- 一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
- 对于任何非空引用值 x,x.equals(null) 都应返回 false。
Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
参数:
obj - 要与之比较的引用对象。
返回:
如果此对象与 obj 参数相同,则返回 true;否则返回 false。