- 以String为例:
public class Demo {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "ab"+"c";
String Str3 = new String("abc");
int i1 = System.identityHashCode(str1);
int i2 = System.identityHashCode(str2);
int i3 = System.identityHashCode(Str3);
System.out.println("str1中地址:"+i1);
System.out.println("str2中地址:"+i2);
System.out.println("str3中地址:"+i3);
}
}
运行结果:
System.identityHashCode()方法打印的是变量内容指向的地址
- 堆栈图:
此时对于str1来说,有两个地址,其自身在栈中存储的地址和内容指向的地址(String池中串的地址)
str2与str1保存的内容在编译时期就被确认为指向同一String串(String池中的串)
此时对于str3来说,有两个地址,其自身在栈中存储的地址和内容指向的地址(堆中匿名对象的地址)
对于堆中new String()来说,有两个地址,其自身在堆中存储的地址(即str3内容指向的地址)和内容指向的地址(String池中串的地址)
- " == "
判断的是内容的地址
即对于str1和str2来说,比较的是两者内容指向的同一地址
即对于str1和str3来说,比较的是两者内容指向的不同地址(String池中的地址和堆中匿名对象的地址)
- equals:
判断的是内容本身
对于str1,str2,str3来说,比较的都是最终指向的String池中字符串的具体内容(String类重写过equals方法)
//String的equals方法
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) { //比较字符串中每个字符是否相同
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}