简体   繁体   English

为什么Eclipse Java编译器检查是否从null强制转换?

[英]Why does the Eclipse Java compiler check casts from null?

Consider the following Java snippet: 考虑以下Java代码段:

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

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

        use(x);
    }
}

The Java bytecode produced for main() by the Eclipse 3.7 compiler looks like this: 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

On the contrary, this is the bytecode produced by the OpenJDK 1.6.0b22 compiler: 相反,这是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

Note that the Eclipse compiler issues an extra checkcast opcode. 请注意,Eclipse编译器会发出额外的checkcast操作码。 It also seems to do that only for arrays and not for any other variable type. 它似乎也只对数组执行此操作,而不对其他任何变量类型执行此操作。

My questions: 我的问题:

  1. As far as I know, null is assignable to any class, including arrays. 据我所知, null可分配给任何类,包括数组。 Does it make any sense at all to checkcast a known null value? checkcast一个已知的null值有任何意义吗?

  2. Does the extra checkcast affect performance? 额外的checkcast是否会影响性能?

  3. Could this be considered a bug in the Eclipse Java compiler? 可以认为这是Eclipse Java编译器中的错误吗?

NOTE: 注意:

I can partially answer (2), at least as far as the OpenJDK 1.6.0b22 JVM is concerned. 至少就OpenJDK 1.6.0b22 JVM而言,我可以部分回答(2)。 I performed a simple benchmark with several assignments to null in a timed tight loop. 我在一个时间紧的循环中执行了一个简单的基准测试,并分配了多个null I could not detect any consistent performance difference, one way or the other. 我无法检测到任何一种或另一种一致的性能差异。

That said, my benchmark was simple enough that any half-decent optimizer would have probably made it useless, so it may not be indicative of a real world application. 就是说,我的基准测试非常简单,以至于任何一个像样的优化器都可能使它失效,因此它可能并不表示实际的应用程序。 I would expect that the JVM would always optimize out that checkcast opcode, but that may not be the case. 我希望JVM 总是会优化该checkcast操作码,但事实并非如此。

  1. No, it doesn't make sense to check, as null is always castable to any reference type. 不,检查没有意义,因为null始终可转换为任何引用类型。 But it doesn't hurt anything. 但这没有任何伤害。
  2. Any decent JIT will optimize the check away anyway (it's effectively a no-op), so the biggest cost is the three bytes that the instruction takes up. 任何体面的JIT无论如何都会优化检查(实际上是无操作),因此最大的开销是指令占用的三个字节。
  3. I wouldn't consider it a "bug", as the generated bytecode works as intended -- it'll never trigger a ClassCastException , as the value is always known and correct -- and, as you apparently saw, there's not a real performance difference either way. 我不会将其视为“错误”,因为生成的字节码将按预期工作—它将永远不会触发ClassCastException ,因为该值始终是已知且正确的,并且正如您所看到的那样,没有真正的性能两种方式都不同。 It's an opportunity for improvement, but nothing that will break in any case. 这是一个改进的机会,但是在任何情况下都不会失败

As for your first question, you are right, the checkcast instruction there is redundant. 至于您的第一个问题,您是对的,那里的checkcast指令是多余的。 According to Sun's Java Hotspot wiki null checks and instance checks are cheap. 根据Sun的Java Hotspot Wiki,空检查和实例检查很便宜。

I've opened an issue in Eclipse Bugzilla to get feedback from Eclipse compiler team, but as it been pointed out before, it is redundant, but harmless check. 我已经在Eclipse Bugzilla中打开了一个问题,以获取Eclipse编译器团队的反馈,但是正如之前所指出的那样,它是多余的,但无害的检查。 It only affects the bytecode size and Java HotSpot compiler will likely apply type check optimization at the runtime. 它仅影响字节码大小,并且Java HotSpot编译器可能会在运行时应用类型检查优化。

Update: from Eclipse compiler team it seem like as side effect of another old bug . 更新: 从Eclipse编译器团队看来,这似乎是另一个旧bug的副作用。

它可能与javac中的一个已知错误有关: 生成的代码中不必要的检查

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么Java编译器有时允许取消装箱为空? - Why does the Java compiler sometimes allow the unboxing of null? Eclipse编译Java代码错误-编译器为null - Eclipse Compiling Java Code Error - Compiler is null 为什么eclipse不会将编译器切换到Java 8? - Why won't eclipse switch the compiler to Java 8? 为什么Eclipse Java编译器会抱怨内部派生类型的未经检查的强制转换? - Why does the Eclipse Java compiler complain about an unchecked cast for inner derived types? 为什么Java编译器允许在三元运算符中将null转换为基本类型 - Why does Java compiler allow casting null to primitive type in ternary operator 学习Java编译器API,为什么trees.getElement(treepath)返回null? - Learning Java Compiler APIs,why does trees.getElement(treepath) return null? Java编译器会优化手动转换以解决强制重载吗? - Will the Java compiler optimize away casts for manual overload resolution? 为什么Eclipse生成的equals()实现在类型检查(instanceof)之前检查null? - Why does the equals() implementation generated by Eclipse check for null before type checking (instanceof)? 为什么要使用结果集!= null是否检查null - why to use resultset!=null does it check for null 为什么Java编译器不对数组进行实习? - Why java compiler does not interns arrays?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM