关于java:Integer与int详解

6次阅读

共计 1960 个字符,预计需要花费 5 分钟才能阅读完成。

说说上面代码的输入:

Integer a1 = 10, b1 = 128;
Integer a2 = 10, b2 = 128;
Integer a3 = new Integer(10);
Integer b3 = new Integer(128);

System.out.println(a1==a2);//true
System.out.println(a1==a3);//false
System.out.println(b1==b2);//false
System.out.println(b1==b3);//false

上述代码详解

Integer 为援用对象, 那么两个 Integer 对象应用 ”==” 比拟的就是空间地址, 如果 a1==a2 那就阐明 a1 与 a2 的空间地址是雷同的, 为什么会雷同呢?b1 与 b2 的空间地址又为什么不雷同了呢?
实际上对于第一与第二行代码,java 在编译期做了优化, 实际上执行的代码如下

Integer a1 = = Integer.valueOf(10);

那么为什么应用 valueOf 办法创立 Integer 对象时 a1 与 a2 的空间地址是雷同的而 b1 与 b2 的空间地址又不同了呢? 下图为 valueOf 办法的源码

从图中能够看到对不同的值会采纳不同的创立形式, 这所有仿佛都与 IntegerCache 这个对象无关,cache 为缓存的意思, 不难猜出如果合乎 if 中的条件则从缓存中获取一个对象, 不合乎则会 new 一个对象. 上面进入到类 IntegerCache 中看看. 正文为起初增加

private static class IntegerCache {
//IntegerCache.low 的值为 -128, 被 final 润饰示意必须赋值且赋值后便不可再次更改
    static final int low = -128;
    //high 值虽也被 final 润饰但并未赋初值, 意味着要在前面赋初值
    static final int high;
    // 用来存储缓存的 Integer 对象
    static final Integer cache[];
    static {
        int h = 127;
// 从虚拟机配置中获取配置 "java.lang.Integer.IntegerCache.high" 的值, 能够本人批改虚拟机配置, 默认没有该条配置
        String integerCacheHighPropValue =
       sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
// 将获取的 String 配置值转为 int
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
// 配置的值若超过 int 类型能示意的最大值, 必定是不行的, 同时也是因为缓存的对象都是存在了数组中而数组的大小也是有上线的, 超过数组最大下限就缓存不下了
                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++);
        assert IntegerCache.high >= 127;
    }
    private IntegerCache() {}
}

综上能够看出在不批改虚拟机配置的状况下,Integer 会在第一次调用 valueOf 办法时将 -128 与 127 的 Integer 对象进行缓存. 所有应用 valueOf 获取的 Integer 对象若在范畴 -128~127 则都为缓存中的同一对象, 而不在范畴内的值则会从新 new 一个 Integer 对象. 回过头再看看开始的代码输入, 是否跟料想的后果统一了呢

若想比拟 Integer 与 Integer 的大小, 应用 equals 比拟即可

再来看看上面代码的输入

Integer a1 = new Integer(100); 
int a2 = 100;
Integer a3 = new Integer(100);
// 当一个根本类型和一个包装类型比拟时,包装类型会被主动拆包进行比拟
System.out.println(a1 == a2);//true
//equals 办法外部调用了 intValue 办法, 该办法会返回 Integer 对象中应用 int 润饰的 value 值, 这个过程就是所谓的拆包
System.out.println(a1 == a3);//false
System.out.println(a1.equals(a3));//true
正文完
 0