Java自动拆箱空指针异常

一、什么是自动装箱和拆箱

自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。 因为这里的装箱和拆箱是自动进行的非人为转换,所以就称作为自动装箱和拆箱。

例子:

public static void main2(String[] args) {
        Integer a = 2; //自动装箱, 语法糖
        int b = a;  //自动拆箱,语法糖
    }

二、自动拆箱引起的空指针异常

自动拆箱,当包装对象为null时,会引起npe异常,例子:

 public static void main2(String[] args) {
        Integer a = null; 
        int b = a;  
    }

报错:

Exception in thread "main" java.lang.NullPointerException
	at com.example.teasure.doamin.TestOpenNpe.main(TestOpenNpe.java:11)

三、原因

反编译上述代码,如下:

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=3, args_size=1
         0: iconst_2
         1: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
         4: astore_1
         5: aload_1
         6: invokevirtual #3                  // Method java/lang/Integer.intValue:()I
         9: istore_2
        10: return
      LineNumberTable:
        line 10: 0
        line 11: 5
        line 12: 10
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      11     0  args   [Ljava/lang/String;
            5       6     1     a   Ljava/lang/Integer;
           10       1     2     b   I
    MethodParameters:
      Name                           Flags
      args

#1可以看出,自动装箱其实是调用了包装类型的valueOf()函数。

#6可以看出,自动装箱其实是调用了包装类型对象的xxxValue()函数。

实际执行代码如下:

    public static void main(String[] args) {
        Integer a = null; //自动装箱, 语法糖
        Integer a = Integer.valueOf(null); //实际执行
        int b = a;  //自动拆箱,语法糖
        int b = a.intValue(); //实际执行
    }

对照代码,如果a为null的话,那么在调用intValue方法时便会抛出NullPointerException。

所以,本质上来讲,所谓的自动拆箱和装箱只不过是Java提供的语法糖而已。

四、引申

函数中入参与出参的拆箱同理,以下代码皆会引起npe异常

    public static Integer getA() {
        return null;
    }

    public static void setA(int a) {
        return;
    }

    public static void main1(String[] args) {
        int a = getA(); //npe
        Integer b = null;
        setA(b); //npe
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值