如何在JAVA中比较两个String对象

记录一下,最近在 JAVA 中比较两个 String 对象遇到的一个小坑。

问题

最近写程序的时候,遇到了需要比较两个 String 对象是否相等的情况,我习惯性的写了形如if(a == "a"){}的语句,IDEA 跳出警告,内容如下:

1
String values are compared using '==', not 'equals()'.

也就是说我刚刚那句话应该写成if(a.equals("a")){}才对,果然不再标红了。

说明

那么,为什么会这样呢?==equals()分别是什么效果呢?

对于基本数据类型byte(字节型)、short(短整型)、int(整型)、long(长整型)、float(单精度浮点型)、double(双精度浮点型)、boolean(布尔型)、char(字符型),==比较的就是他们的值,也不存在equals()方法。

而对于String这样的引用数据类型,==比较的是两个对象的引用地址即内存地址是否相同,如果内存地址相同,自然就是同一个对象了,同一个对象之间有啥好比的。

我们一般的应用场景主要是要比较两个 String 对象的内容,那就需要使用equals()方法。我们可以看一下java.lang.Stringequals()方法的定义,可以看到equals()才是在比较两个 String 对象的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
* Compares this string to the specified object. The result is {@code
* true} if and only if the argument is not {@code null} and is a {@code
* String} object that represents the same sequence of characters as this
* object.
*
* @param anObject
* The object to compare this {@code String} against
*
* @return {@code true} if the given object represents a {@code String}
* equivalent to this string, {@code false} otherwise
*
* @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;
}

还有一个特例的情况,比如"abcde" == "abcde"或是"abcde" == "abc" + "de"都是会返回true的,因为双方都是由编译器直接实现的,没有被声明为变量。

小结

当然,如果你知道自己在做什么,就是要利用==的这个特性,自然是没有问题的。其他时候用equals()方法即可。