为什么 Eclipse Java 编译器会检查 null 类型转换?

问题描述 投票:0回答:3

考虑以下 Java 片段:

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. 额外的
  3. checkcast

    会影响性能吗?

    
    

  4. 这可以被视为 Eclipse Java 编译器中的错误吗?
  5. 注意:

我可以

部分地

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


也就是说,我的基准测试非常简单,任何半点优化器都可能使其毫无用处,因此它可能并不代表现实世界的应用程序。我希望 JVM 会

总是

优化该checkcast操作码,但情况可能并非如此。

    

java eclipse null bytecode
3个回答
2
投票
Sun 的 Java Hotspot wiki

空检查和实例检查很便宜。 我在 Eclipse Bugzilla 中打开了一个

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

更新:来自 Eclipse 编译器团队

这似乎是

另一个老错误的副作用。


2
投票
null
    始终可转换为任何引用类型。 但没有什么坏处。
  1. 任何像样的 JIT 都会优化检查(它实际上是无操作),因此最大的成本是指令占用的三个字节。
  2. 我不会认为它是一个“错误”,因为生成的字节码按预期工作——它永远不会触发
  3. ClassCastException
  4. ,因为该值总是已知且正确的——而且,正如您显然看到的那样,没有无论哪种方式,都有真正的性能差异。 这是一个改进的机会,但无论如何都不会“破坏”。
  5.     
    它可能与 javac 中的一个已知错误有关:
生成的代码中不必要的检查

0
投票

© www.soinside.com 2019 - 2024. All rights reserved.