软件构造tips——int自动装箱的等价性

软件构造tips——int自动装箱的等价性

在复习软件构造的时候遇到了问题:int封装成Integer后的等价性。这个问题比较有趣,通过查看Integer源码,找到了其中的规律。

问题:

 public static void main(String[] args){
Integer p1=new Integer(2);
Integer p2=new Integer(2);
System.out.println (p1==p2);
System.out.println (p1.equals(p2));

Integer p3=2;
Integer p4=2;
System.out.println (p3==p4);
System.out.println (p3.equals(p4));

Integer p5=200;
Integer p6=200;
System.out.println (p5==p6);
System.out.println (p5.equals(p6));
}

如图,代码分为三部分。第一部分是使用了new Integer直接构造新的Integer对象。第二部分是直接赋值一个小的整数。第三部分则是赋值一个大整数。那么这三种情况下代码的运行情况如何呢?他们的结果分别是:

false
true

true
true

false
true

为什么会有这样的结果呢?2和200得到的结果为什么是相反的呢?

解释

可以看到三种情况下equals方法得到的结果都是true,这是理所当然的,因为equals方法已经被重写。它只关心对象中储存的值是否相等。

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

但是对于==来说,结果分别是false ,true ,false。首先我们来分析第一种情况:

情况1
Integer p1=new Integer(2);
Integer p2=new Integer(2);

这种情况非常简单,因为p1,p2都是新建的Integer对象,他们的地址显然不同,那么==必然得到false。

情况2
Integer p3=2;
Integer p4=2;

我们必须先了解直接赋值法是如何创建与一个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);
}

这里有一个判断,如果传入的参数 i在[low ,high]范围内,此方法返回数组IntegerCache.cache中的一个对象,否则创建一个新对象。查看IntegerCache的源码后,我们得知IntegerCache的low定义为-128,high默认定义为127。也就是说如果参数i在这个范围内,该方法将直接拿到cache数组中现存的Integer而无需新建。如果在此范围之外,那么不好意思,你必须花费内存来储存你想要的i了。
那么对于本问题而言,因为我们给出的i是2,那么它将直接获得缓存数组的对象。因此p3与p4都将指向同一个地址,==的结果自然为true。

情况3

分析完情况2后这个也就一目了然了。因为我们给出的值是200。200已经超出了缓存数组的范围,必须新建两个对象,因此==的结果为false。

总结

在对老师ppt上提出的等价性问题进行挖掘后发现了生成Integer的有趣机制。这种缓存机制有利于在生成大量Integer对象时减少内存的消耗。比如淘宝网一天生成无数个-128——127之间的小整数,只需要一个地址就足够了。
遇到问题多看java源码,会有很多收获。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值