Java自动装箱与自动拆箱


Java自动装箱与自动拆箱

  1. Java自动装箱与自动拆箱的实现
  2. 何时会触发自动装箱与拆箱
  3. 常见题目

基本数据Java类型: 对应包装器类:

  • int (4byte) Integer
  • byte (1byte) Byte
  • short (2byte) Short
  • long (8byte) Long
  • float (4byte) Float
  • double (8byte) Double
  • char (2byte) Character
  • boolean (未定) Boolean
Integer i = 10;	// 装箱	-- Integer.valueOf(10)
int n = i;		// 拆箱	-- i.intValue()

装箱的时候自动调用的是Integer的valueOf(int)方法

拆箱的时候自动调用的是Integer的intValue方法

扩展

范例一:

Integer integer400 = 400;
int int400 = 400;
System.out.println(integer400 == int400);	

== 运算 -> integer400 拆箱,结果为true

范例二:

Integer integer100=100;
int int100=100;
System.out.println(integer100.equals(int100));

方法中参数类型 -> 根据方法参数列表的类型 自动选择 装箱or拆箱,结果为int装箱,true

范例三:

Integer integer100 = 100;
int int100 = 100;
Long long200 = 200l;
System.out.println(integer100 + int100);
System.out.println(long200 == (integer100 + int100));
System.out.println(long200.equals(integer100 + int100));

+、-、*、/ 运算,自动拆箱

  1. System.out.println(integer100 + int100); +号两边自动拆箱,相加,结果自动装箱,调用toString()

  2. long200 == (integer100 + int100); +号两边自动拆箱,获得结果后 long200 拆箱,比较

  3. long200.equals(integer100 + int100) +号两边自动拆箱,获得结果后自动装箱(Integer),Inteter类型和Long类型进行equals比较,结果为false

(两个 int 类型相加 ,自动装箱类型为Integer)

范例四:

Integer a = 1;
Integer b = 2;
Long g = 3L;
Long h = 2L;

System.out.println(g.equals(a+h));

g.equals(a+h); a+h 自动拆箱,a为int + h为long,结果为long,自动装箱为Long类型,结果为true

范例五:

Integer integer100 = null;
int int100 = integer100;

编译期不会报错

运行时:NullPointerException

问题:int int100 = integer100;

​ integer100 自动拆箱时,null.intValue()

范例六:

Integer i1=100;
Integer i2=100;
Integer i3=300;
Integer i4=300;

i1 == i2; // true
i3 == i4; // false

i1、i2、i3、i4 均为Integer类型

i1与i2这两个Integer类型的引用指向了同一个对象,而i3与i4指向了不同的对象

装箱时调用的是 Integer.valueOf(100)

// valueOf 的源码
public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];	
    else
        return new Integer(i);
}

当i>=-128且i<=IntegerCache.high时,直接返回IntegerCache.cache[i + 128]

IntegerCache为Integer的内部静态类

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

        // high value may be configured by property
        int h = 127;
        if (integerCacheHighPropValue != null) {
            // Use Long.decode here to avoid invoking methods that
            // require Integer's autoboxing cache to be initialized
            int i = Long.decode(integerCacheHighPropValue).intValue();
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - -low);
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }
    
	private IntegerCache() {}
}

IntegerCache有静态成员变量cache,为一个拥有256个元素的数组。

在IntegerCache中也对cache进行了初始化,即第i个元素是值为i-128的Integer对象。

而-128至127是最常用的Integer对象,这样的做法也在很大程度上提高了性能。

也正因为如此,“Integeri1=100;Integer i2=100;”,i1与i2得到是相同的对象。

  • 当封装类与基础类型进行==运算时,封装类会进行拆箱,拆箱结果与基础类型对比值;

  • 而两个封装类进行==运算时,与其它的对象的比较一样,对比两个对象的地址,也即判断是否两个引用是否指向同一个对象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值