细节8 含义不同——使用“==”与equals比较对象
可以使用关系相等运算符“==”和对象的equals ()方法比较对象,但是在比较对象时,两者是有区别的。
· 关系相等运算符“==”
当使用关系相等运算符“==”比较对象时,比较的是对象的引用是否相同,如果对象的引用相同,则比较的结果就为true,否则比较的结果就为false。
· 对象的equals ()方法
当使用对象的equals ()方法比较对象时,是比较对象的内容(即对象的值)是否相同,而不是比较对象的引用,所以只要两个对象的内容相同,则使用equals ()方法比较的结果就为true,否则比较的结果就为false。
示例:
String x = new String ("Java"); // 创建String对象x,其值是Java String y = new String ("Java"); // 创建String对象y,其值也是Java
上面的代码创建了两个String对象x和y,它们的内容在内存中被存储到不同的位置,如图5.11所示。
图5.11 对象x和y的内存分布
对如图5.11所示的两个对象x和y使用关系相等运算符“==”与对象的equals ()方法进行比较,其结果是不同的,示例如下:
String x = new String ("Java"); // 创建String对象x,其值是Java String y = new String ("Java"); // 创建String对象y,其值也是Java System. out. println (x==y); // 用关系相等比较对象x和y System. out. println (x. equals (y)); // 用对象的equals ()方法比较对象x和y
本示例运行后将输出如下两行信息:
false true
说明
通过本示例的输出结果可以看出,对于如图5.11中所示的两个对象x和y,通过关系相等运算符“==”进行比较的结果为false,这也充分说明关系相等运算符“==”比较的是对象的引用,虽然对象x和y的内容相同,但是由于引用不同,所以认为x和y是两个不同的对象;而用对象的equals ()方法比较的结果为true,这也充分地说明了对象的equals ()方法比较的是对象的内容,而与对象的引用无关。
接下来再看一个示例:
String x = "Java"; // 创建String对象x,其值是Java String y = "Java"; // 创建String对象y,其值也是Java
上面的代码创建了两个String对象x和y,它们的内容在内存中存储在相同的位置,也就是同一个对象,就好比两个人住在同一个房子中,如图5.12所示。
图5.12 对象x和y的内存分布
对如图5.12中所示的两个对象x和y使用关系相等运算符“==”与对象的equals ()方法进行比较,其结果都是真值true,代码如下:
String x = "Java"; // 创建String对象x,其值是Java String y = "Java"; // 创建String对象y,其值也是Java System. out. println (x==y); // 用关系相等比较对象x和y System. out. println (x. equals (y)); // 用对象的equals ()方法比较对象x和y
本示例运行后将输出如下两行信息:
true true
说明
本示例输出的两行信息之所以都是真值true,是因为这两个对象的引用与内容都相同,所以无论使用的是关系相等运算符“==”,还是对象的equals ()方法,其比较结果都为真值true,这样创建的两个对象x和y之所以相同,是因为将相同的字符串常量赋值给不同的字符串变量时,使用了缓存数据,所以这两个对象的引用与内容是完全相同的。
提示
String类使用的equals ()方法比较的是字符串的内容是否相同,这是由于String类重写了Object类的equals ()方法,而Object类的equals ()方法则是比较对象的引用是否相同,所以当需要比较其他对象时,可以通过重写Object类的equals ()方法来定制如何比较对象。