在java开发中String的操作非常常见,而String操作中又经常使用到String中的equals方法,但是很多时候对这个方法估计还有些模糊。今天我们就来谈谈这个equals方法。
equals方法是属于根类Object的,**默认比较的是对象的地址值**。在String中我们可以使用“==”比较地址值,所以再使用equals方法比较地址值意义不大,很多时候我们需要比较的是String具体的内容。所以String类中就进行了equals方法覆写。String中覆写之后的equals方法比较的就是具体的内容是否相同。以上的内容对于学java的人来说估计都是非常熟悉的,那么我们来看看几个例子:
String s ="hello";
String t = new String("hello");
char[] c ={'h','e','l','l','o'};
System.out.println(s.equals(t));
System.out.println(t.equals(c));
System.out.println(s == t);
System.out.println(t.equals(new String("hello")));
System.out.println(t.equals(new StringBuffer("hello")));
以上的输出结果:
true
false
false
true
false
为什么会有这有的结果呢?如果你心里对结果已经非常清楚了,那么以下内容你可以忽略不看了,不然就让我们一起往下剖析:
String s的内容值是“hello”,String t的内容值也是“hello”,而String中equals比较的就是内容值是否相同,所以进行s.equals(t)比较的时候因为s和t的内容值一样所以结果是**true**
所以`System.out.println(s.equals(t));`输出为ture
紧接着就是大家容易犯糊涂的地方了。char[] c的内容一看也是“hello”组成的,String s的内容值也是“hello” ,所以容易想当然就认为t.equals(c)结果是true。如果你也认为是true,那么证明这里你也是糊涂的。为什么true是错的呢。我们来看看String中equals方法的源码。
1. public boolean equals(Object anObject) {
2. if (this == anObject) {
3. return true;
4. }
5. if (anObject instanceof String) {
6. String anotherString = (String) anObject;
7. int n = value.length;
8. if (n == anotherString.value.length) {
9. char v1[] = value;
10. char v2[] = anotherString.value;
11. int i = 0;
12. while (n-- != 0) {
13. if (v1[i] != v2[i])
14. return false;
15. i++;
16. }
17. return true;
18. }
19. }
20. return false;
21. }
好了,通过查看源码我们发现第5行使用了instanceof关键字进行了对象类型的判断,就是这一句关键的代码影响了程序最后的结果。我们来看看t.equals(c)中c是char数组类型,所以执行到第5行的时候char数组类型肯定不属于String,所以if中代码不执行,直接执行第20行返回false。
所以System.out.println(t.equals(c));输出结果false.
接下来我们之前说了引用数据类型中“==”比较的是地址值,String s ="hello",s的地址指向的是常量池中的"hello";而String t = new String("hello");因为有了new的操作,所以t指向的是堆内存中的地址,两个地址肯定不一样,所以System.out.println(s == t);输出结果是false;
有了上面的知识做铺垫,那么接下来的结果就好判断了。System.out.println(t.equals(new String("hello")));中使用equals比较的String的内容值,new String("hello")是一个String的匿名对象,类型依然也是String,所以equals比较结果是true.
System.out.println(t.equals(new StringBuffer("hello")));中equals传入的参数是StringBuffer,StringBuffer不属于String类型所以源码中第5行的结果又是false,跳过if中的代码直接执行第20行返回false.