从对象到布尔值的强制转换是有效的 Java 语言吗?

2022-09-04 20:36:08

我在工作中偶然发现了一个旧的Java代码,该代码是多年前由C程序员实现的,我们忍不住开始讨论该代码 - 即使它编译并工作 - 实际上是有效的Java代码。

final Object o = Boolean.TRUE;
boolean b = (boolean) o;

这本质上是有问题的代码。正如你所看到的,从Object到原始布尔值有一个不太好的投射,这应该是不可能的,但碰巧有效,这要归功于一些隐含的拳击魔术。

如果我执行以下操作

final Object o = Boolean.TRUE;
if (o instanceof Boolean) {
  b = (boolean) o;
}

我甚至在o被投射到b的行上得到一个警告,说“Cast与给定的实例不兼容”。这显然是正确的,但由于隐含的拳击,它仍然有效。

现在的问题是:Java规范是否真的允许这种强制转换,因此应该与未来的JVM版本一起使用?还是它只是碰巧在当前版本中工作,并且在将来的JVM更新中可能不再工作?


答案 1

这在 JLS 8 第 5.5 节中定义。它特别允许通过从到基元类型的拆箱转换进行转换(另请参阅表 5.5-A)。具体来说,JLS说:Object

通过取消装箱转换,引用类型的表达式可以进行强制转换为基元类型而不会出错。

有关更多详细信息,请参阅我对类似问题的回答:Java 6 与 Java 7 之间自动拆箱的差异


答案 2

是的。这是合法的。请参阅 JLS-5.1.8。拆箱转换,其中显示(部分)

取消装箱转换将引用类型的表达式转换为基元类型的相应表达式。具体而言,以下八种转换称为“取消装箱”转换

  • 从布尔类型到布尔类型

推荐