文章目录
  1. 1. 首先理解拆箱和装箱
  2. 2. 问题
  3. 3. 原理分析
  4. 4. 问题解决

首先理解拆箱和装箱

  基本数据类型的 自动装箱 ( autoboxing )、 拆箱 ( unboxing )是自J2SE 5.0开始提供的功能。 一般我们要创建一个类的对象实例的时候,我们会这样: Class a = new Class(parameters); 当我们创建一个 Integer 对象时,却可以这样: Integer i = 100; ( 注意:和 int i = 100 ;是有区别的 ) 实际上,执行上面那句代码的时候,系统为我们执行了: Integer i = Integer.valueOf(100) ; 这里暂且不讨论这个原理是怎么实现的(何时拆箱、何时装箱),也略过普通数据类型和对象类型的区别。我们可以理解为,当我们自己写的代码符合装(拆)箱规范的时候,编译器就会自动帮我们拆(装)箱。
**

问题

看一下下面这段代码

Map map = new HashMap();
Boolean b = (map!=null ? map.get(“test”) : false);

这段代码是存在问题的,执行该代码,会报NPE.

Exception in thread “main” java.lang.NullPointerException

反编译后代码如下:

HashMap hashmap = new HashMap();
Boolean boolean1 = Boolean.valueOf(hashmap == null ? false : ((Boolean)hashmap.get(“test”)).booleanValue());

可以确定((Boolean)hashmap.get(“test”)).booleanValue() 的执行过程会报空指针。

原理分析

官方api描述:

 If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.

 If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.

 If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.

  简单的来说就是:当第二,第三位操作数分别为基本类型和对象时,其中的对象就会拆箱为基本类型进行操作。

  所以,结果就是:由于使用了三目运算符,并且第二、第三位操作数分别是基本类型和对象。所以对对象进行拆箱操作,由于该对象为null,所以在拆箱过程中调用null.booleanValue()的时候就报了NPE。

问题解决

如下保证二三目是对象就可以避免:

Map map = new HashMap();
Boolean b = (map!=null ? map.get(“test”) : new Boolean(false));

文章目录
  1. 1. 首先理解拆箱和装箱
  2. 2. 问题
  3. 3. 原理分析
  4. 4. 问题解决