128 陷阱

128 陷阱

128陷阱,简单来说就是对大于等于128和小于等于-129的数字,使用 Integer 类型存储(自动装箱)时候

使用 == 进行比较地址,会返回 false

表现

public class Test {  
    public static void main(String[] args) {  
        Integer num1 = 127;  
        Integer num2 = 127;  
        System.out.println(num1 == num2);  
        Integer num3 = 128;  
        Integer num4 = 128;  
        System.out.println(num3 == num4);  
        Integer num5 = -128;  
        Integer num6 = -128;  
        System.out.println(num5 == num6);  
        Integer num7 = -129;  
        Integer num8 = -129;  
        System.out.println(num7 == num8);  
    }  
}

输出结果为:

true
false
true
false

原因

产生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);  
}

其中 low 在源码中为:

static final int low = -128;

high 在源码中为:

static final int high;

虽然这样看 high 的初始值为 0

但在静态构造块中:

static {  
    // high value may be configured by property  
    int h = 127;  
    String integerCacheHighPropValue =  
        sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");  
    if (integerCacheHighPropValue != null) {  
        try {  
            int i = parseInt(integerCacheHighPropValue);  
            i = Math.max(i, 127);  
            // Maximum array size is Integer.MAX_VALUE  
            h = Math.min(i, Integer.MAX_VALUE - (-low) -1);  
        } catch( NumberFormatException nfe) {  
            // If the property cannot be parsed into an int, ignore it.  
        }  
    }  
    high = h;  
  
    cache = new Integer[(high - low) + 1];  
    int j = low;  
    for(int k = 0; k < cache.length; k++)  
        cache[k] = new Integer(j++);  
  
    // range [-128, 127] must be interned (JLS7 5.1.7)  
    assert IntegerCache.high >= 127;  
}

high 赋值了 127

由此也得出了不会产生128陷阱情况的范围 [-128, 127]

现在再回到最初的 valueOf() 方法,可以看出,当结果在 [-128, 127] 之间的时候,会直接 return IntegerCache.cache[i + (-IntegerCache.low)];

而超出此范围的值,会 return new Integer(i) 会在内存中开辟一份新的空间,此时返回的值的内存地址就不会是一开始的内存地址了

现在我们再来看 IntegerCache.cache

static final Integer cache[];

而在静态构造快中又存在这样一部分:

cache = new Integer[(high - low) + 1];  // new Integer[127 + 128 + 1] -> new Integer[256]
int j = low;  // j = -128
for(int k = 0; k < cache.length; k++)  
    cache[k] = new Integer(j++);

在源码的静态构造块中,创建了一个缓存数组,来存放 [-128, 127] 范围的数字

再次回到 valueOf() 源码查看,得出,当结果在 [-128, 127] 范围内是,直接返回的是一个数值,并非新创建了一个 Integer 实例,即 return 127; 返回这样的值。

故而得出了产生128陷阱的原因,归根结底就是源码中的缓存数组,如果这个数组变大了,那么就不会是128陷阱了,就变成更大的129陷阱,130陷阱等等了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值