我们经常看到这么一句话,Java中==比较的是对象的引用,而equals方法比较的是对象的内容。这句话到底对不对,我们进行一次测试。
Java作为一种面向对象的语言,其中的变量主要有int, char...等等基本类型,和各种的类型实例化对象的引用变量。Java中用来测试对象的相等性有两种方法,一种是使用关系操作符 == 来进行比较,另一种是使用Java的Object类中定义的equals( )方法。
其中==操作符是用来比较对象的引用,若两个引用指向的是同一个对象,则返回的是 true,否则返回的则是false。
而equals( )方法只能用于对象的比较,不能用在基本类型比较,(所以Java中的基本类型只能使用==操作符进行相等性判断)在Object类中的定义如下:
public
boolean
equals(Object
obj
) {
return
(
this
==
obj
);
}
显而易见的是,在定义equals方法时,Object类使用的是 == 操作符。如果直接调用Object类的equals方法,实际就是使用了==操作符来测试两个对象是否相等,是没有意义的。所以在使用该方法时要注意是否重写过。测试如下:
public
class
EqualTest {
int
flag
= 0;
public
static
void
main(String[]
args
){
EqualTest
etOne
=
new
EqualTest();
EqualTest
etTwo
=
new
EqualTest();
etOne
.
flag
= 1;
etTwo
.
flag
= 1;
println(
etOne
.equals(
etTwo
));
etTwo
=
etOne
;
println(
etOne
.equals(
etTwo
));
}
}
输出结果:
false
true
显然,在自己未重写equals方法时,调用equals方法就等同使用==操作符,只有在两个引用指向同一个对象时才返回true。所以Java类库中的绝大多数类都重写了equals方法,拿String类来说,他重写了方法,使其功能变为比较对象的内容,不同的对象内容相同时,也返回true。其中重写的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
;
}
测试一下:
public
class
EqualTest {
int
flag
= 0;
public
static
void
main(String[]
args
){
String
one
=
"Hello Java"
;
String
two
=
new
String(
"Hello Java"
);
String
three
=
one
;
println(
one
==
two
);
println(
one
.equals(
two
));
println(
one
==
three
);
}
}
output:
false
true
true
显然,String类在调用equals方法时,是调用了自身重写的方法,比较的是String类的内容。所以要实现比较内容的功能,必须在类里重写equals方法。否则就等同于使用==操作符。