Java的自动拆箱和装箱

【转载】详解Java的自动装箱与拆箱(Autoboxing and unboxing)

什么是拆箱装箱

拆箱就是自动将包装器类型转换为基本数据类型。(Integer——> int)
装箱就是自动将基本数据类型转换为包装器类型。(int ——> Integer)
在这里插入图片描述
这个过程是自动执行的。

public class Main {
    public static void main(String[] args) {
    //自动装箱,系统自动执行:Integer emp= Integer.valueOf(9);
    Integer emp= 9;

    //自定拆箱,系统自动执行 :int empprim = emp.intValue();
    int totalprim = emp;
    }
}
装箱
  • Integer emp= Integer.valueOf(9);
    valueOf(int i)源码:如果i小于-128或者大于等于128(不在-128~128之间),就创建一个Integer对象,否则执行SMALL_VALUES[i + 128]。

     public static Integer valueOf(int i) {
     	return  i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
     }
    

    Integer类的构造函数:

    private final int value;
    
    public Integer(int value) {
    	this.value = value;
    }
    
    public Integer(String string) throws NumberFormatException {
    	this(parseInt(string));
    }
    

    SMALL_VALUES:静态的Integer数组对象。已经被创建好了的,也就是说在i >= 128 || i < -128会创建不同的对象,在i < 128 && i >= -128会根据i的值返回已经创建好的指定的对象

    private static final Integer[] SMALL_VALUES = new Integer[256];
    
  • 例如:

    		Integer i1 = 100;
            Integer i2 = 100;
            Integer i3 = 200;
            Integer i4 = 200;
    
            System.out.println(i1==i2);  //true
            System.out.println(i3==i4);  //false
    

    100<128,会返回SMALL_VALUES里面创建好的同一个对象。所以i1和i2是同一个对象。
    200>128,自动装箱执行new Integer(200),也就是说它们会分别创建两个不同的对象。

    因为对于Integer,在(-128,128]之间只有固定的256个值,所以为了避免多次创建对象,我们事先就创建好一个大小为256的Integer数组SMALL_VALUES,所以如果值在这个范围内,就可以直接返回我们事先创建好的对象就可以了。
    但是Double类型会有无限个,所以不能提前创建,valueOf()直接创建新的对象。在这里插入图片描述
    Boolean类型:并没有创建对象,因为在内部已经提前创建好两个对象,因为它只有两种情况,这样也是为了避免重复创建太多的对象。
    public static Boolean valueOf(boolean b) {
    return b ? Boolean.TRUE : Boolean.FALSE;
    }

  • 另一种情况:包装类与基本数据类型比较。
    = =:说明num1 == num2时自动拆箱。
    什么时候拆箱:
    当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算。
    当 “==”运算符的两个操作数都是包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。

    Integer num1 = 400;  
    int num2 = 400;  
    System.out.println(num1 == num2); //true
    

    equals:源码里先将基本数据类型装箱,然后比较值。

    Integer num1 = 100;  
    int num2 = 100;  
    System.out.println(num1.equals(num2));  //true
    

    源码:需要满足装箱后的类型相同以及内容相同。

    public boolean equals(Object o) {
        return (o instanceof Integer) && (((Integer) o).value == value);
    }
    
拆箱:
  • intValue():

    public int intValue() {
    	return value;
    }
    
  • 举例:

    Integer integer100 = null;  
    int int100 = integer100;
    

    这两行代码是完全合法的,完全能够通过编译的,但是在运行时,就会抛出空指针异常。其中,integer100为Integer类型的对象,它当然可以指向null。但在第二行时,就会对integer100进行拆箱,也就是对一个null对象执行intValue()方法,当然会抛出空指针异常。所以,有拆箱操作时一定要特别注意封装类对象是否为null。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值