"==" 一般用于基本数据类型,它比较的是两者的值,而对于引用数据类型,"=="比较的却是两个引用 (即栈中的内容),而引用类型正真的值是放在堆中的(即new出来的对象),euqals()比较的才是堆中的值。
一、引用数据类型
看一下Object中的equals();方法:
public boolean equals(Object obj) {
return (this == obj);
}
即比较的是实际的对象(堆中),先看一张内存存储图:
创建s1和s2,在堆中分别开辟两个空间存放,而s3 = s2 只是把s2的引用赋给s3。可得出以下结论:
s1 == s2 // false
s2 == s3 // true
s1.equals(s2) // false
s2.equals(s3) // true
所以证明了,在引用数据类型中 "==" 比较的是引用(栈)是否相同,而equals()比较的是两者实际对象(堆)是否是同一个。
二、String
接下来看一个特殊的类--String。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;
}
它是逐个字符判断,看两个字符串是否有相同的字符组成。而说到String,还要提起一个内存空间,即常量池,如图:
new 出来的对象还是放在堆中,但String s = "helloJava"; 像这种却是放在常量池中,常量池的特点是:常量池的字符串常量,不能重复出现,也就是说,在定义多个常量时,编译器先去常量池查找该常量是否已经存在,如果不存在,则在常量池创建一个新的字符串常量;如果该常量已经存在,那么新创建的String类型引用指向常量池中已经存在的值相同的字符串常量,也就是说这是不在常量池开辟新的内存。
代码测试:
public class StirngTest {
public static void main(String[] args) {
String str1 = "java";
String str2 = "java";
String str3 = new String("java");
String str4 = new String("java");
System.out.println( str1==str2 );//true
System.out.println( str1==str3 );//false
System.out.println( str3==str4 );//false
System.out.println( str1.equals(str2) );//true
System.out.println( str1.equals(str3) );//true
System.out.println( str3.equals(str4) );//true
}
}
String 中 "==" 还是比较其引用,而equals();比较的是字符串是否一致(重写了)。
三、基本数据类型
类型 | 字节 |
---|---|
byte | 1 |
short | 2 |
int | 4 |
long | 8 |
char(UTF-16) | 2 |
float | 4 |
double | 8 |
基本数据类型只能采用 "==" 来做比较。
===============友情链接===============
http://blog.csdn.net/sinat_32430939/article/details/70989731