【问题标题】:java ternary operator internals + intellij evaluate expressionjava三元运算符内部+ intellij评估表达式
【发布时间】:2018-05-30 13:37:13
【问题描述】:

这段代码会抛出 NPE:

Integer wtf = false ? 1 : (Integer) null;

问题是,如果第二个或第三个操作数是 int,那么另一个也将转换为 int。 (根据JLS这部分的表格https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25

我的第一个问题是,为什么要这样写规范?将值转换为更具表现力的选项(整数)而不是更原始的选项(整数)不是更有意义吗?为了防止这种极其混乱的错误?

第二个问题是,您可以在 Intellij 的评估表达式中成功地评估该表达式。结果将是分配了 null 的 wtf 对象。是错误,还是在某处指定它不符合 JLS?

【问题讨论】:

  • "第二个问题...是不是 bug" 是的,那将是 intellij 中的一个 bug。
  • 仅供参考:Google 容易出错has a check for this
  • 如果 intellj 将其设置为 null,那么这绝对是一个错误,因为 eclipse 正确地抛出了空指针异常。 JLS为什么会这样?只有写过这个的人才能回答。也许是为了更好的性能。
  • 很遗憾 JLS 的作者没有像 ISO 标准委员会 did for the C language 那样发布基本原理文件。
  • 对于第二个问题,让我把它颠倒过来:是否有任何地方指定 IntelliJ“评估表达式” 符合 JLS 标准?还是只是假设?

标签: java intellij-idea ternary-operator jls


【解决方案1】:

为什么要这样写规范?

我无法回答为什么,因为我没有编写规范。但我可以提出一个不应该不然的原因。

当第二个和第三个参数的类型不同,并且两种类型都可以转换为数字类型时,它们会经历binary numeric promotion。这与采用数字操作数的其他运算符相同,例如+.

如果您尝试添加intInteger null,您可以获得相同的NPE:

System.out.println(1 + (Integer) null);

在这种情况下,您无法通过将 1 装箱到 Integer.valueOf(1) 来做任何有用的事情。

如果在 +?: 运算符 (*) 之间以不同方式处理数字类型,则会出现不一致。并且条件运算符需要使用某种形式的二进制数字提升,以便能够处理不同类型的原始操作数,例如intdouble

看一眼specification for the conditional operator 应该会让您相信它的类型处理已经非常复杂了(参见表 15.25-A 到 E),因此不应该变得更复杂。

不幸的是,你能以这种方式射中自己的脚;但这就是语言的样子。

我认为这里的问题在于自动装箱是一种通用语言功能;没有它,就不会有这样的问题,因为你必须自己拆箱。


(*) 实际上,它的行为确实有点不同。例如,(Integer) null + (Integer) null 会自动拆箱,而condition ? (Integer) null : (Integer) null自动拆箱。之所以出现这种差异,是因为条件运算符指定在应用二进制数值提升之前检查相同的操作数类型。

【讨论】:

  • 我想说,在 ?: 运算符中处理原始+它的包装器组合时使用包装器类不会更复杂。即使现在这种情况下也没有使用 BNP.. 但是好的,但这可能是其中之一,双方的论点都没有明显更好。
【解决方案2】:
  • 我猜原因是效率和简单性:更少的内存和直接访问,而不是通过 Integer 包装对象。否则,例如。 G。在Integer wtf = 40 + (false ? Integer.valueOf("1") : 2)); 中,必须生成一个 Integer 实例作为中间结果。
    通过使用 Java 5 装箱/拆箱,您所指的表变得必要。在 Java 1.4 中,第二个和第三个操作数不允许同时使用 intInteger
  • 是的,这是一个错误,因为它违反了 JLS。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    相关资源
    最近更新 更多