目录
1.2. ==在比较引用数据类型时判断的是引用数据类型的地址是否相等
1.3.1.==在比较基本数据类型和其包装类时,会先将包装类进行自动拆箱,在进行比较
==在底层的比较原理
1.1. ==在比较基本数据类型时,判断的是值是否相等
int a = 10;
int b = 20;
int c = 10;
int d = a;
System.out.println(a == b);//false,两个值不相等
System.out.println(a == c);//true,值相等
System.out.println(a == d);//true,将a赋值给d后,两个值均为10
System.out.println(c == d);//true,值相等
其他基本类型类似。
1.2. ==在比较引用数据类型时判断的是引用数据类型的地址是否相等
1.2.1.==并不能用于类之间进行比较是否相等
1.2.2.==可以判断String这种引用类型变量比较
先看一下下面的代码
String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");
String str4 = str1+"d";
String str5 = "abcd";
String str6 = "abc"+"d";
System.out.println(str1 == str2);//true
System.out.println(str1 == str3);//false
System.out.println(str4 == str5);//false
System.out.println(str4 == str6);//false
System.out.println(str5 == str6);//true
(1)==比较String类型时比较的是二者的地址是否相同,相同为true,不同为false,str1和str2的地址都是常量池中"abc"的地址,地址一样,所以返回true.
(2)对于str3和str2的比较,因为是String str3 = new String(“abc”);这句话他创建了两个对象,一个是字面值“abc”的对象,一个是new String()对象。而此处 str3装的是new String()对象的地址,但str1装的是字面值的地址。地址不同,所有比较后返回的便是false。即str3是重新new出来的对象,所以和str1必不相同,返回false
(3)对于str4和str5及str6的比较
此处str5创建了一个字面值"abcd"并存放到了常量池中,所有str6创建的时候直接重用,两个的地址值相同。但后面str1和"d"拼接了一个abcd赋值给了str4,但不再指向开始的常量值,所以最后比较时返回的是false。
1.3. ==在比较基本数据和其包装类时
1.3.1.==在比较基本数据类型和其包装类时,会先将包装类进行自动拆箱,在进行比较
int a = 100;
Integer b = 100;
Integer c = 100;
Integer d = new Integer(100);
Integer e = 10000;
Integer f = 10000;
System.out.println(a == b); //true
System.out.println(b == c);//true
System.out.println(b == d);//false
System.out.println(e==f);//false
比较a和b时,会先进行自动拆箱,在JDK底层实现拆箱
public int intValue() {
return value;
}
拆箱是直接返回value值,所以所有的int和Integer比较时,只要值相同就会返回true
Integer和Integer类型比较时会比较复杂一些
当赋值为int类型时,则会进行自动装箱
@IntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
其中low 是常量-128,high是赋值的常量127
因此,在自动装箱时,[-128,127]的值会存入内存中,而不在这个范围内的则会创建一个Integer对象。所以在[-128,127]范围的值则直接是比较大小,对于超出这个范围的,其实质是比较这两个地址是否相同。因为是重新new出来的所以超出这个范围的会返回false,。
对于比较b和d时,因为d是直接new出来,不涉及自动装箱过程,会直接比较地址。
1.3.2 对于其他包装类,在装箱过程中,没有存入内存的动作
@IntrinsicCandidate
public static Double valueOf(double d) {
return new Double(d);
}
所以在其他非Integer包装类比较时,都是直接比较地址。