如何在JAVA中比较字符串(string)?
我们有两个字符串a和b,如何比较它们呢?用==
还是.equals()
?
==
和.equals()
有什么区别
==
比较的左右两侧的值。当左右两侧为基本类型的时候,直接比较值,当左右两侧为引用类型的时候,比较的是引用本身的值。字符串变量为引用类型,因此==
比较的是字符串引用本身的值。.equals()
一般是java类中声明的比较方法,比较自己和另一个实例是否为同一个值。string
类型已经实现了.equals()
方法,会比较自身和另一个字符串是否相等。
为什么有时候==
在相同字符串的时候会返回true
查看下列代码:
String val1 = "val";
String val2 = "val";
// 输出为 true
System.out.println(val2 == val1);
因为字符串在java中非常常用,出于性能和复用的考虑,代码中直接声明的字符串会直接在字符串常量池中初始化,而且只初始化一次,后续使用都会引用这个常量。
val1 = 字符串常量池引用 ===> 字符串本体(位于常量池中)
val2 = ↑
可以看到,val1
和val2
的是同一个值,因此val1 == val2
会返回true。
但是,当代码变成下面这样的时候:
String val1 = "val";
String val2 = new String("val");
// 输出为 false
System.out.println(val2 == val1);
上面的val2会在堆中新建一个对象,而不是常量池的对象,如下所示:
val1 = 字符串常量池引用 => 字符串本体(位于常量池中)
val2 = 字符串堆中对象引用 => 字符串本体(位于堆中)
因此两个引用的值并不相等。
如何正确使用.equals()
在上面的第二个例子中,很明显两个字符串是一样的,但是直接用==
会得出false的结果,这时候就要使用equals了。
但是,.equals()
使用也有要注意的地方:
当一个字符串常量和一个字符串变量比较时,要保持常量在前面。比如"张三".equals(name)
,而不是name.equals("张三")
。这样可以保证在name
为null时,仍然可以获得比较的结果,如果反着写,就会得到一个空指针异常了。
当两个变量比较时,最好使用Objects.equals
,比如比较两个名字是否一样,可以写成Objects.equals(name1,name2)
。Objects.equals
会在内部调用对象的equals,并且会提前判断变量是否为空,防止出现空指针异常。