JDK11中三元表达式为何抛出NPE?另一写法却正常?
问题原因解析
核心逻辑:三元运算符的类型统一规则
Java的三元条件运算符(?:)会自动对两个分支的结果类型做统一化处理,这个规则直接导致了两段代码的行为差异:
第一段代码抛NPE的原因
代码:
Boolean sortAsc = Objects.nonNull(chooseRequest) ? chooseRequest.getSortAsc() : false;
- 分支1:
chooseRequest.getSortAsc()返回Boolean包装类型,可能为null - 分支2:
false是boolean基本类型
根据Java类型转换的优先级,当一个分支是包装类型、另一个是基本类型时,三元运算符会将结果统一为基本类型。这意味着如果分支1返回null,JVM会尝试把这个Boolean类型的null拆箱成boolean基本类型,而null拆箱必然抛出NullPointerException。
第二段代码正常运行的原因
代码:
Boolean sortAsc = Objects.nonNull(chooseRequest) ? null : false;
- 分支1:
null属于Boolean类型的空引用(引用类型) - 分支2:
false是boolean基本类型
此时三元运算符会优先统一为引用类型Boolean——因为null只能属于引用类型。JVM会把分支2的false自动装箱成Boolean.FALSE,整个表达式的结果是Boolean类型,赋值给sortAsc时不会触发拆箱操作,自然不会抛NPE。
修复方案
如果要避免第一段代码的NPE,只需让两个分支都保持Boolean类型,比如把false改成Boolean.FALSE:
Boolean sortAsc = Objects.nonNull(chooseRequest) ? chooseRequest.getSortAsc() : Boolean.FALSE;
内容的提问来源于stack exchange,提问作者qingbin xu
相关产品推荐
相关产品推荐

