Integer对象与int数据类型在使用中的常见问题

1、类型转换问题  

 JDK 1.5后 对基本数据类型提供了自动拆装箱方法, 我们再Integer对象与int类型互转时只需要一行代码来实现了

        Integer a = 10; //自动装箱
        int b = a;    //自动拆箱
        int c = 5;    
        Integer d = c; //自动装箱
        System.out.println(b+",,"+d); 

自动拆装箱都做了些什么,可以看一下编译后的class文件

       Integer a = Integer.valueOf(10); //装箱
        int b = a.intValue(); //拆箱
        byte c = 5;
        Integer d = Integer.valueOf(c);//装箱
        System.out.println(b + ",," + d);

那么问题就来了 这里面的坑就是 Integer是对象,允许 null值出现,在拆箱时 一定要对Integer对象进行非空校验,否则 拆箱时就会报空指针异常了。

2、大小判断

Integer a = 189;
int d=189;
Integer b = 189;
Integer c = 199;
System.out.print("a>c");
System.out.println(a>c);
System.out.print("a==b");
System.out.println(a==b);
System.out.print("a==d");
System.out.println(a==d);

a>c false
a==b false

a==d true

这里面比较容易产生疑惑的就是 a和b都是189 为什么是false

编译后class内容

Integer a = Integer.valueOf(189);
short d = 189;
Integer b = Integer.valueOf(189);
Integer c = Integer.valueOf(199);
System.out.print("a>c");
System.out.println(a.intValue() > c.intValue());
System.out.print("a==b");
System.out.println(a == b);
System.out.print("a==d");
System.out.println(a.intValue() == d);

这里可以看到 做不等判断时 Ingteger对象都进行了自动拆箱 以int类型进行比较 结果在预想之内

那么对比Integer对象判等 和 Integer对象与int数据类型判等的过程

与int类型判等时是先拆箱成了int类型,判等结果为true

区别在于 两个Integer对象 依旧是以Integer对象进行判等的,

这里分析一下Integer对象判等的问题

我们可以看下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 >= IntegerCache.low && i <= IntegerCache.high

范围内,这个范围是什么呢?

看一下Integer对象的这个方法

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    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;
    }

    private IntegerCache() {}
}

 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");

这个java虚拟机配置(可自行配置)不大于127的情况下 是 -128 与127之间,拉回到

public static Integer valueOf(int i)

当我们定义的Integer对象在这个范围内时,会去从cache中取初始化好的对象,所以即使我们定义多个,也一直是同一个对象,地址永远相同,

而超过这个范围的Integer对象都是新new的Integer对象,每个对象的地址都不同,

恰巧 “==”运算符在比较对象时是比较的地址,所以造成了上面的不解

可以试一下 

Integer a = 10 ;
Integer b = 10;
System.out.println(a==b);//true
Integer a = 200;
Integer b = 200;
System.out.println(a==b);//false


你可能感兴趣的:(java基础)