1、==和equals的区别
==运算符比较的是栈中存放的值是否相等,而equals比较的是堆中存放的值是否相等。
2、String类型变量的==和equals
字符串常量均存储在字符串缓冲池中,当将一个字符串常量赋给一个变量时,首先会在字符串缓冲池中寻找是否有该字符串,如果有则将该字符串的地址赋给字符串常量,因此对于stringData0和stringData1使用==是相等的,而使用new运算符则会在堆中创建分配内存用于存储该字符串的值并将该地址赋给该变量,每次使用new关键字均执行该操作,所以stringData0和stringObject0和stringObject1均是不同的。
String
stringData0
=
"a string"
;
String
stringData1
= String.valueOf(
"a string"
);
String
stringObject0
=
new
String(
"a string"
);
String
stringObject1
=
new
String(
"a string"
);
System.
out
.println(
"stringData0==stringData1 : "
+ (
stringData0
==
stringData1
));
System.
out
.println(
"stringData0==stringObject0 : "
+ (
stringData0
==
stringObject0
));
System.
out
.
println
(
"stringObject0==stringObject1 : "
+ (
stringData0
==
stringObject0
));
System.
out
.println(
"stringData0.equals(stringData1) : "
+ (
stringData0
.equals(
stringData1
)));
System.
out
.println(
"stringData0.equals(stringObject0) : "
+ (
stringData0
.equals(
stringObject0
)));
System.
out
.println(
"stringObject0.equals(stringObject1) : "
+ (
stringObject0
.equals(
stringObject1
)));
输出是:
stringData0==stringData1 : true
stringData0==stringObject0 : false
stringObject0==stringObject1 : false
stringData0.equals(stringData1) : true
stringData0.equals(stringObject0) : true
stringObject0.equals(stringObject1) : true
2、int类型变量的==和equals
Java为每一个基础数据类型都提供了相应的包装类,将一个基本数据类型赋给其包装类相当于执行了
public
static
Integer valueOf(
int
i
)
(以Integer为例),该方法的源码如下(JDK 8):
public
static
Integer valueOf(
int
i
) {
if
(
i
>= IntegerCache.
low
&&
i
<= IntegerCache.
high
)
return
IntegerCache.
cache
[
i
+ (-IntegerCache.
low
)];
return
new
Integer(
i
);
}
其中
static
final
int
low
= -128;
static
final
int
high = 127;
可以看到当传入的值大于-128小于127则将返回整型缓冲池的该变量的地址否则new一个对象,既然是缓冲池那么其机制和字符串缓冲池是一样的,先去查看缓冲池中是否有该值,如果有则返回该值的地址否则在缓冲池中创建一个新的变量并将该变量的内存地址返回。因此对于20和200会出现不同的结果。
Integer
intObject0
= 20;
Integer
intObject1
= Integer.valueOf(20);
Integer
intObject2
=
new
Integer(20);
System.
out
.println(
"intObject0==intObject1 : "
+ (
intObject0
==
intObject1
));
System.
out
.println(
"intObject1==intObject2 : "
+ (
intObject1
==
intObject2
));
System.
out
.println(
"intObject0.equals(intObject1) : "
+ (
intObject0
.equals(
intObject1
)));
System.
out
.println(
"intObject1.equals(intObject2) : "
+ (
intObject1
.equals(
intObject2
)));
Integer
intObject3
= 200;
Integer
intObject4
= Integer.valueOf(200);
Integer
intObject5
=
new
Integer(200);
System.
out
.println(
"intObject3==intObject4 : "
+ (
intObject3
==
intObject4
));
System.
out
.println(
"intObject4==intObject5 : "
+ (
intObject4
==
intObject5
));
System.
out
.println(
"intObject3.equals(intObject4) : "
+ (
intObject3
.equals(
intObject4
)));
System.
out
.println(
"intObject4.equals(intObject5) : "
+ (
intObject4
.equals(
intObject5
)));
输出:
intObject0==intObject1 : true
intObject1==intObject2 : false
intObject0.equals(intObject1) : true
intObject1.equals(intObject2) : true
intObject3==intObject4 : false
intObject4==intObject5 : false
intObject3.equals(intObject4) : true
intObject4.equals(intObject5) : true
3、Object的equals与其他类的object
默认的Object提供的equals方法仍然是比较两个对象的地址,而其他类的equals均重写了该equals方法,使用equals比较两个对象的值是否相等。源码如下:
object的equals方法
public
boolean
equals(Object
obj
) {
if
(
obj
instanceof
Integer) {
return
value
== ((Integer)
obj
).intValue();
}
return
false
;
}
String的equals方法
public
boolean
equals(Object
anObject
) {
if
(
this
==
anObject
) {
return
true
;
}
if
(
anObject
instanceof
String) {
String
anotherString
= (String)
anObject
;
int
n
=
value
.
length
;
if
(
n
==
anotherString
.
value
.
length
) {
char
v1
[] =
value
;
char
v2
[] =
anotherString
.
value
;
int
i
= 0;
while
(
n
-- != 0) {
if
(
v1
[
i
] !=
v2
[
i
])
return
false
;
i
++;
}
return
true
;
}
}
return
false
;
}
Integer的equals方法
public
boolean
equals(Object
obj
) {
if
(
obj
instanceof
Integer) {
return
value
== ((Integer)
obj
).intValue();
}
return
false
;
}
附:可见其他类的object均重写了equals方法,是的equals比较的是对象是否相等而不是存放对象的地址
最后附上该程序的源码如下:
package
javabase;
public
class
TestEquals {
public
static
void
main(String[]
args
) {
String
stringData0
=
"a string"
;
String
stringData1
= String.valueOf(
"a string"
);
String
stringObject0
=
new
String(
"a string"
);
String
stringObject1
=
new
String(
"a string"
);
System.
out
.println(
"stringData0==stringData1 : "
+ (
stringData0
==
stringData1
));
System.
out
.println(
"stringData0==stringObject0 : "
+ (
stringData0
==
stringObject0
));
System.
out
.println(
"stringObject0==stringObject1 : "
+ (
stringData0
==
stringObject0
));
System.
out
.println(
"stringData0.equals(stringData1) : "
+ (
stringData0
.equals(
stringData1
)));
System.
out
.println(
"stringData0.equals(stringObject0) : "
+ (
stringData0
.equals(
stringObject0
)));
System.
out
.println(
"stringObject0.equals(stringObject1) : "
+ (
stringObject0
.equals(
stringObject1
)));
Integer
intObject0
= 20;
Integer
intObject1
= Integer.valueOf(20);
Integer
intObject2
=
new
Integer(20);
System.
out
.println(
"intObject0==intObject1 : "
+ (
intObject0
==
intObject1
));
System.
out
.println(
"intObject1==intObject2 : "
+ (
intObject1
==
intObject2
));
System.
out
.println(
"intObject0.equals(intObject1) : "
+ (
intObject0
.equals(
intObject1
)));
System.
out
.println(
"intObject1.equals(intObject2) : "
+ (
intObject1
.equals(
intObject2
)));
Integer
intObject3
= 200;
Integer
intObject4
= Integer.valueOf(200);
Integer
intObject5
=
new
Integer(200);
System.
out
.println(
"intObject3==intObject4 : "
+ (
intObject3
==
intObject4
));
System.
out
.println(
"intObject4==intObject5 : "
+ (
intObject4
==
intObject5
));
System.
out
.println(
"intObject3.equals(intObject4) : "
+ (
intObject3
.equals(
intObject4
)));
System.
out
.println(
"intObject4.equals(intObject5) : "
+ (
intObject4
.equals(
intObject5
)));
}
}