原链接https://www.cnblogs.com/dolphin0520/p/3780005.html
以下是我个人总结:
Integer a1=127;
Integer a2=127;
System.out.println(a1==a2);//true
Integer a3=128;
Integer a4=128;
System.out.println(a3==a4);//false
上面的代码a1与a2的地址相同,但是a3和a4的地址不同,是因为做了自动装箱
Integer a5=128;
//Integer a5=Integer.valueOf(128);
Integer a5=128;代码实际上是运行的Integer.valueOf(128);这就是自动装箱操作
Integer.valueOf源码
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
可以看出valueOf方法,判断传入的值是否在-128到127之间,如果在那么直接返回缓存池当中的值,如果不在范围内,那么返回new Integer对象。
所以Integer a1=127;Integer a2=127;这里都指向的是缓存池中的值,==比较地址当然一样了。
Integer a3=128;Integer a4=128;超出了范围,返回的是new Integer对象,指向了两个不同的堆内存,当然内存地址不一样了。
需要注意的是,如果直接new Integer(5),这样是不会走缓存池的,还是指向堆内存。
Double i1 = 100.0;
Double i2 = 100.0;
Double i3 = 200.0;
Double i4 = 200.0;
System.out.println(i1==i2);//false
System.out.println(i3==i4);//false
上面又与Integer不同,全部打印false
Double的valueOf源码
public static Double valueOf(double d) {
return new Double(d);
}
可以看到Double的valueOf没有判断范围然后取缓存,而是直接返回的 new Double 对象。
(在某个范围内的整型数值的个数是有限的,而浮点数却不是。浮点数不好事先做缓存)
Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
Double、Float的valueOf方法的实现是类似的。
public class Main {
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
Long h = 2L;
System.out.println(c==d);
System.out.println(e==f);
System.out.println(c==(a+b));
System.out.println(c.equals(a+b));
System.out.println(g==(a+b));
System.out.println(g.equals(a+b));
System.out.println(g.equals(a+h));
}
}
打印
true
false
true
true
true
false
true
第一个和第二个输出结果没有什么疑问。第三句由于 a+b包含了算术运算,因此会触发自动拆箱过程(会调用intValue方法),因此它们比较的是数值是否相等。而对于c.equals(a+b)会先触发自动拆箱过程,再触发自动装箱过程,也就是说a+b,会先各自调用intValue方法,得到了加法运算后的数值之后,便调用Integer.valueOf方法,再进行equals比较。同理对于后面的也是这样,不过要注意倒数第二个和最后一个输出的结果(如果数值是int类型的,装箱过程调用的是Integer.valueOf;如果是long类型的,装箱调用的Long.valueOf方法)。
网友评论