如何在JAVA中比较字符串(string)?
如何在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,并且会提前判断变量是否为空,防止出现空指针异常。