Java之三目运算符

 某日,同事给我展示了一块代码,问我有没有什么问题。(代码如下 代码块1):

int i = 1;
Boolean a = null;
boolean b = false;
System.out.println(i == 1 ? a : b);

集智慧与美貌于一身的我一眼就发现了其中的端倪:当然会报 NPE 了!

但是如果代码变成这样的呢(如下 代码块2)?

int i = 1;
boolean a = true;
Boolean b = null;
System.out.println(i == 1 ? a : b);

上述代码块就是正常的。

为什么呢?

这就涉及到了Java中 三目运算符 和 自动装箱/拆箱 的问题了。

代码块1会报错是因为条件满足,取 a 的值。在取 a 的值时,三目运算符中既有基本类型,又有引用类型;JVM会帮我们把引用类型的数据转换为基本类型。通过查看 class 文件看到如下代码(代码块3):

int i = 1;
Boolean a = null;
boolean b = false;
System.out.println(i == 1 ? a.booleanValue() : b);

因为 a 是引用类型,此时调用 a 的方法就会报NPE了。

代码块2为什么不会报错呢?

此时三目运算符中的条件满足,直接就取 a 的值了,因为 a 是基本类型的,直接就拿来用了,所以程序正常。可以看到 class 文件如下(代码块4):

int i = 1;
boolean a = true;
Boolean b = null;
System.out.println(i == 1 ? a : b.booleanValue());

但在实际的业务场景中,我们的代码不会上上述一样是 i == 1 的写法,大部分情况下是动态判断的。如何避免踩进上述的坑中呢?

其实要解决这个问题也很简单,就是不让JVM帮我们拆箱。即把 a 和 b 两个对象都改为 Boolean 或 boolean,只要两个对象统一就好了。

避免采坑的代码:

int i = 1;
Boolean a = Boolean.TRUE;
Boolean b = Boolean.FALSE;
System.out.println(i == 1 ? a : b);

int i = 1;
boolean a = true;
boolean b = false;
System.out.println(i == 1 ? a : b);

总结:

不止 Boolean/boolean 有这个问题,像 Byte / byte、Integer / int、Short / short、Long / long、Character / char、Float / float、Double / double 都会有这样的问题。只要代码规范一点,就不会坑到队友啦  ╮( ̄▽ ̄)╭

 

最后祝大家码出好心情,码出幸福人生!

 

你可能感兴趣的:(java基础)