[英]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: 我的问题:
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
值有任何意义吗?
Does the extra checkcast
affect performance? 额外的checkcast
是否会影响性能?
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
操作码,但事实并非如此。
null
is always castable to any reference type. 不,检查没有意义,因为null
始终可转换为任何引用类型。 But it doesn't hurt anything. 但这没有任何伤害。 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.