[JAVA]为什么==和equals总让新手迷惑? 详解 关系操作符 == 和 equals
Posted zhengxl5566
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JAVA]为什么==和equals总让新手迷惑? 详解 关系操作符 == 和 equals相关的知识,希望对你有一定的参考价值。
关系操作符==和 类的equals方法都可以用来比较两个类是否相同,但实际用起来却经常产生令JAVA新手迷惑的结果。
先看一段示例代码:
public class HelloWorld { public static void main(String[] args) { // TODO Auto-generated method stub //System.getProperties().list(System.out); String str1 = new String("Hello world!"); String str2 = new String("Hello world!"); System.out.println("str1==str2:"+ (str1==str2)); System.out.println("str1.equals(str2):"+str1.equals(str2)); } }
输出:
str1==str2:false
str1.equals(str2):true
为什么都是对类进行比较,结果却不一样呢?当我们搞清楚两种比较方式的原理之后,问题就迎刃而解了。
1、关系操作符 == 和 !=
关系操作符生成的是一个boolean结果,它们计算的是操作数的值之间的关系。也就是说,==和!= 只比较两边的值是否相等。
对于JAVA来说,一切都是对象,对于对象的操作都是通过引用实现的。
str1和str2虽然内容都是"Hello world!",但却是通过两次new开辟出来了两块空间存放的,引用str1和str2指向的是不同的空间,也就是他们的地址是不一样的,所以 str==str2结果是false
2、equals方法
JAVA中所有的类都继承自Object基类,打开Object.java的源码可以看到equals方法的实现:
public boolean equals(Object obj) { return (this == obj); }
可以看到,Object.java中对equals的实现就是简单的用==对比一下。
那为什么输出了 str1.equals(str2):true 呢,是不是String中对equals进行了重写?
下面是String.java中equals方法的实现代码:
* @see #compareTo(String) * @see #equalsIgnoreCase(String) */ 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; }
可以看到,String类确实重写了equals方法,它将字符串的每一个字符进行了比较,完全相同的字符串就会输出true。
这就解释了 str1.equals(str2):true
类似的情况还有Integer、Double、Long等,读者可以自行验证
总结一下:
1、关系操作符==和!= 比较的是两边的值
2、equals方法如果未被重写则比较的是引用的地址(其实也是对值进行比较),如果被重写了那就具体情况具体分析了,诸如Integer、Double、Long等基本类型的封装类都重写了equals方法用来比较所指对象的内容
以上是关于[JAVA]为什么==和equals总让新手迷惑? 详解 关系操作符 == 和 equals的主要内容,如果未能解决你的问题,请参考以下文章
java equals()和 ‘==’,‘!=’的使用和易错点