⾃动装箱与拆箱

装箱是将基本数据类型转为包装器类型;eg:Integer i=200; 是将int类型的200转化为了Integer类型的200,装箱的过程是采用了包装类的valueOf()方法(eg:Integer.valueOf())。

拆箱是将包装类类型转为基本数据类型;eg:int k=i; 是将i是Integer类型的200赋值给了int类型的k,装箱的过程是采用了包装类的xxxValue()方法(eg:Integer.intValue())。

Sint类型的包装器类是Integer;char类型的包装器类是Character;short类型的包装器类是Short;byte类型的包装器类是Byte;long类型的包装器类是Long;boolean类型的包装器类是Boolean;float类型的包装器类是Float;double类型的包装器类是Double。

Integer i=100;
Integer k=100;
System.out.println(i==k);
Integer m=200;
Integer n=200;
System.out.println(m==b);

结果是true false,i和k指向的是同一个对象,而m和n指向的是不同的对象;因为自动装箱采用的Integer.valueOf(100)方法,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);
}

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() {}
    }

在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。

Double i=100;
Double k=100;
System.out.println(i==k);
Double m=200;
Double n=200;
System.out.println(m==b);

结果是false false,i和k指向的是不是同一个对象,m和n也指向的是不同的对象;因为自动装箱采用的Double.valueOf(100)方法,Double的valueOf()方法源码:

    public static Double valueOf(double d) {
        return new Double(d);
    }

在通过valueOf方法创建Double对象的时候是直接创建一个新的Double对象。

        Boolean i=true;
        Boolean k=true;
        System.out.println(i==k);
        Boolean m=false;
        Boolean n=false;
        System.out.println(m==n);

结果是true true,i和k指向的是同一个对象,m和n也指向的是同一个的对象;因为自动装箱采用的Boolean.valueOf( )方法,Boolean的valueOf()方法源码:

public static final Boolean TRUE = new Boolean(true);   
public static final Boolean FALSE = new Boolean(false); 
public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
}

TRUE 和FALSE是在Boolean中定义了2个静态成员属性,指向相同。

Integer i = new Integer(xxx)和Integer i =xxx;这两种方式的区别:

  1)第一种方式不会触发自动装箱的过程;而第二种方式会触发自动装箱的过程;

  2)在执行效率和资源占用上的区别。第二种方式的执行效率和资源占用在一般性情况下要优于第一种情况(注意这并不是绝对的)。

Integer a = 10;
Integer b = 20;
Integer c = 30;
Integer d = 30;
Integer e = 250;
Integer f = 250;
System.out.println(c==d);
System.out.println(e==f);
System.out.println(c==(a+b));
System.out.println(c.equals(a+b));

 当 "=="运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。

对于包装器类型,equals方法并不会进行类型转换。

c==d的结果是true,因为c、d都是Integer类型的,值在-128-127之间,不用创建对象直接指向IntegerCache.cache中已经存在的对象的引用。而e==f的结果是false,值超出了-128-127会创建对象。

c==(a+b)的结果是true,这里a+b包含了算术运算,因此会触发自动拆箱过程(会调用intValue方法),因此它们比较的是数值是否相等,都是30。

c.equals(a+b)的结果是true,a+b包含了算术运算会先触发自动拆箱过程(会调用intValue方法),再触发自动装箱过程(会调用valueOf方法),也就是说a+b,会先各自调用intValue方法,得到了加法运算后的数值之后,便调用Integer.valueOf方法,再进行equals比较。

Integer a = 10;
Integer b = 20;
Long m = 30L;
Long n = 20L;
System.out.println(m==(a+b));
System.out.println(m.equals(a+b));
System.out.println(m.equals(a+n));

m==(a+b) 的结果是true,这里a+b包含了算术运算,因此会触发自动拆箱过程(会调用intValue方法),因此它们比较的是数值是否相等,都是30。

m.equals(a+b)的结果是false;a+b包含了算术运算会先触发自动拆箱过程(会调用intValue方法),再触发自动装箱过程(会调用valueOf方法),也就是说a+b,a+b的类型是Integer,而m的类型是Long。所以是false。

m.equals(a+n)的结果是true;a+n包含了算术运算会先触发自动拆箱过程(会调用intValue方法和longValue方法),再触发自动装箱过程(会调用valueOf方法),也就是说a+b,a+b的类型是Long,而m的类型是Long。所以是true。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值