首先想一下下面的代码输出是怎样的?
public static void main(String[] args) {
String a = "a" + "b" + "2";
String b = "ab2";
System.out.println( a == b);
String a1 = "a" + "b" + "2";
String b1 = new String("ab2");
System.out.println( a1 == b1);
}
输出结果:
哦什么情况,发现结果和自己想想的有差距耶。
关于“==”
在Java语言中,当用“==”匹配时,就是比较两个内存单元的内容是否一样。
如果是基本类型byte、boolean、short、char、int、float、double,就是直接比较的他们的值。
如果是引用类型,比较的就是引用的值,“引用的值”可以被认为是对象逻辑地址。如果引用类型用“==”就是比较的两个对象的地址是否相同。
那么为什么例子中a与b指向了同一个内存单元?
这就是JVM的“编译时优化”,当编译器在编译代码:String a = "a" + "b" + "2"; 时,会将其编译为,String a = "ab2"; 。因此 a == b 为true。
关于equals()
说到 “==” 不得不说一下equals()。
equals()是在Object类中被定义的,它的定义中就是使用 == 来匹配,也就是说如果不重写equals() 比较的也是引用地址。
equals()的存在就是为了希望子类去重写,用于比较值,不去比较引用地址。
String 类中的就是重写了equals(), 如下:
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;
}
所以我们在比较String时都是用了equals()方法。
总结:
“==” 基本类型比较值,引用类型比较引用地址。
String “+” 操作 JVM编译时会做优化。
equals()方法,不重写比较的也是引用地址。