Consider the following Java snippet:
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:
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:
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. 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. Does it make any sense at all to checkcast
a known null
value?
Does the extra checkcast
affect performance?
Could this be considered a bug in the Eclipse Java compiler?
NOTE:
I can partially answer (2), at least as far as the OpenJDK 1.6.0b22 JVM is concerned. I performed a simple benchmark with several assignments to null
in a timed tight loop. 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.
As for your first question, you are right, the checkcast instruction there is redundant. According to Sun's Java Hotspot wiki null checks and instance checks are cheap.
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. It only affects the bytecode size and Java HotSpot compiler will likely apply type check optimization at the runtime.
Update: from Eclipse compiler team it seem like as side effect of another old bug.