当前位置: 首页 > 面试题库 >

Java自动装箱和三元运算符的疯狂

许琛
2023-03-14
问题内容

仅仅花了几个小时调试以下代码:

    LinkedHashMap<String, Integer> rsrqs = new LinkedHashMap<String, Integer>();
    Integer boxedPci = 52;
    Integer boxedRsrq = boxedPci != null ? rsrqs.get(boxedPci.toString()) : -1;

上面产生了一个NullPointerException。以下代码没有:

    LinkedHashMap<String, Integer> rsrqs = new LinkedHashMap<String, Integer>();
    Integer boxedPci = 52;
    Integer boxedRsrq = boxedPci != null ? rsrqs.get(boxedPci.toString()) : Integer.valueOf(-1);

唯一的区别是用Integer.valueOf()包装-1。我敢肯定,一旦有人解释了为什么这段代码的行为方式如此,我就会打我的额头。但是有人可以向我解释为什么这段代码的行为方式:)吗?

-编辑

再次考虑,我怀疑NPE来自返回null的rsrqs.get(),我认为Java在将其装箱回Integer之前试图将其拆箱成int。Integer.valueOf()强制Java执行unbox-
box步骤。故事的道德启示; 不要只是忽略Eclipse中的那些拳击警告;)


问题答案:

与任何表达式一样,三元表达式具有由编译器确定的类型。如果三元表达式的两侧具有不同类型的外观,则编译器将尝试使用两个选项中的最小歧义来查找通用的基本类型。在您的情况下,-1至少是最不明确的,因此三元表达式的类型为int。可悲的是,编译器没有使用基于接收变量的类型推断。

rsrqs.get(boxedPci.toString())然后对表达式求值并强制转换为类型,int以匹配三元表达式,但是因为它null会抛出NPE。

通过将装箱-1,三元表达式的值是Integer,因此您是空安全的。



 类似资料:
  • --编辑 再考虑一下,我怀疑NPE来自返回null的rsrqs.get(),我认为java试图在装箱返回整数之前将其解框为int。integer.valueOf()强制Java执行unbox-box步骤。故事的寓意;不要只是忽略Eclipse中的那些拳击警告;)

  • 问题内容: 前几天,我因三元运算符中意外的类型转换而遇到了一个非常奇怪的问题。鉴于此(无用的示例性)功能: 我期望编译后以下两个代码段完全相同: 与 。 事实证明,如果是,则-statement可以正常工作,而第二个代码段中的三元运算则抛出a 。似乎三元运算已决定将这两种选择都强制转换为类型,然后再将结果自动装箱为!?!。实际上,如果我将显式转换为,则该异常消失。换一种说法: 与以下内容不同: 。

  • 问题内容: 为什么会抛出 虽然这不是 解决方案是通过替换false方式Boolean.FALSE来避免null被取消装箱-这boolean是不可能的。但这不是问题。问题是为什么?JLS中是否有任何引用可以证实这种行为,尤其是第二种情况? 问题答案: 别在于方法的显式类型returnsNull()会在编译时影响表达式的静态类型: 参见Java语言规范,第15.25节“ 条件运算符?”。: 对于E1,

  • 本文向大家介绍Java三目运算中隐藏的自动拆装箱,包括了Java三目运算中隐藏的自动拆装箱的使用技巧和注意事项,需要的朋友参考一下 最近修改线上bug的时候排查了一个十分隐藏的bug,直接上代码: 乍一看是没什么毛病的,但是已运行就会发现报空指针,在idea里面也会警告可能有空指针,这是什么原因呢? 直接看字节码: 可以看到字节码中调用了`Integer.valueOf()`方法,因为我们代码中一

  • 我试图理解以下代码在Java中使用数值比较运算符比较2个整数对象时的行为。