【问题标题】:Why does the Eclipse Java compiler check casts from null?为什么 Eclipse Java 编译器检查来自 null 的强制转换?
【发布时间】:2011-09-28 17:03:15
【问题描述】:

考虑以下 Java sn-p:

public class Test {
    public static void use(Object[] x) {
    }

    public static void main(String[] args) {
        Object[] x = null;

        use(x);
    }
}

Eclipse 3.7 编译器为 main() 生成的 Java 字节码如下所示:

public static void main(java.lang.String[]);
  Code:
   0:   aconst_null
   1:   checkcast   #20; //class "[Ljava/lang/Object;"
   4:   astore_1
   5:   aload_1
   6:   invokestatic    #21; //Method use:([Ljava/lang/Object;)V
   9:   return

相反,这是OpenJDK 1.6.0b22编译器产生的字节码:

public static void main(java.lang.String[]);
  Code:
   0:   aconst_null
   1:   astore_1
   2:   aload_1
   3:   invokestatic    #2; //Method use:([Ljava/lang/Object;)V
   6:   return

请注意,Eclipse 编译器会发出一个额外的checkcast 操作码。它似乎也只对数组而不是任何其他变量类型这样做。

我的问题:

  1. 据我所知,null 可以分配给任何类,包括数组。 checkcast 一个已知的 null 值是否任何有意义?

  2. 额外的checkcast 会影响性能吗?

  3. 这是否可以认为是 Eclipse Java 编译器中的错误?

注意:

我可以部分回答 (2),至少就 OpenJDK 1.6.0b22 JVM 而言。我执行了一个简单的基准测试,在定时紧循环中对null 进行了多次分配。我无法以一种或另一种方式检测到任何一致的性能差异。

也就是说,我的基准测试非常简单,任何半体面的优化器都可能使其无用,因此它可能并不代表真实世界的应用程序。我希望 JVM 会总是优化 checkcast 操作码,但情况可能并非如此。

【问题讨论】:

    标签: java eclipse compiler-construction null bytecode


    【解决方案1】:

    至于您的第一个问题,您是对的,那里的 checkcast 指令是多余的。 根据Sun's Java Hotspot wiki,空检查和实例检查很便宜。

    我打开了issue in Eclipse Bugzilla 以获取 Eclipse 编译器团队的反馈,但正如之前指出的那样,这是多余的,但无害的检查。它只影响字节码大小,Java HotSpot 编译器可能会在运行时应用类型检查优化。

    更新:from Eclipse compiler team 似乎是another old bug 的副作用。

    【讨论】:

      【解决方案2】:
      1. 不,检查没有意义,因为null 总是可以转换为任何引用类型。但它不会伤害任何东西。
      2. 无论如何,任何体面的 JIT 都会优化检查(它实际上是无操作),因此最大的成本是指令占用的三个字节。
      3. 我不会将其视为“错误”,因为生成的字节码按预期工作——它永远不会触发ClassCastException,因为该值始终是已知且正确的——而且,正如您显然看到的,两种方式都没有真正的性能差异。这是一个改进的机会,但无论如何都不会破坏

      【讨论】:

        【解决方案3】:

        这可能与 javac 中的一个已知错误有关:Unnecessary checkcast in generated code

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-14
          • 1970-01-01
          • 2014-09-16
          相关资源
          最近更新 更多