资料
java 判断两个字符串相等深入理解Java中的String
本质区别
==
基本int类型,直接比较, 引用类型,比较地址.
一 “==”
"=="
比较的是否为同一个对象,两个不同的字符串对象,即使是相同的,用"=="
还是返回false.
举个例子:
String a = "helloworld";
String b = "helloworld";'
String c = new String("helloworld");
System.out.println(a==b); //输出true
System.out.println(a==c); //输出false
为什么a==b
返回true,而a==c
返回false?
因为JVM为了提高性能和减少内存的开销,在实例化字符串的时候进行了一些优化:使用字符串常量池. 每当我们创建字符串常量时,JVM会首先检查字符串常量池中,那么就直接返回常量池中的实例引用.如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中.由于string字符串的不可变性我们可以十分肯定常量池中不一定存在两个相同的字符串.
也就是说:a和b是同一个字符串的引用,而a与c是不同的对象引用,所以a==b
输出位true,a==c
输出false.
那要想比较两个字符串对象的所有字符是否相同该如何比较,equals()方法.
二 “equals()方法”
equals()是根类Object中的方法在实现时其实也是调用"==",但在String类中重写了此方法(见补充).重写后的equals方法比较两个字符串对象的所有字符是否相同.
equals如何使用
例:A字符串和B字符串比较:
if(A.equals(B)) {
}
源码
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String aString = (String)anObject;
if (coder() == aString.coder()) {
return isLatin1() ? StringLatin1.equals(value, aString.value)
: StringUTF16.equals(value, aString.value);
}
}
return false;
}
@HotSpotIntrinsicCandidate
public static boolean equals(byte[] value, byte[] other) {
if (value.length == other.length) {
for (int i = 0; i < value.length; i++) {
if (value[i] != other[i]) {
return false;
}
}
return true;
}
return false;
}
@HotSpotIntrinsicCandidate
public static boolean equals(byte[] value, byte[] other) {
if (value.length == other.length) {
int len = value.length >> 1;
for (int i = 0; i < len; i++) {
if (getChar(value, i) != getChar(other, i)) {
return false;
}
}
return true;
}
return false;
}
从上面的代码中可以看到:
(1) String类中的equals首先比较地址,如果是同一个对象的引用,可知对象相等,返回true.
(2) 如果不是同一个对象,equals方法挨个比较两个字符串对象内的字符,只有完全相等才返回true,否则返回false.
自己的例子
String str1 = "hello";
String str2 = "world!";
String str3 = "helloworld!";
String str4 = str1+str2;
String str5 = new String("helloworld!");
System.out.println(str3 == str4);//false
System.out.println(str3.equals(str4));//true
System.out.println(str3 == str5);//false
System.out.println(str3.equals(str5));//true