开发者

Why does the Eclipse Java compiler check casts from null?

开发者 https://www.devze.com 2023-04-08 21:03 出处:网络
Consider the following Java snippet: public class Test { public static void use(Object[] x) { } public static void main(String[] args) {

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:

  1. 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?

  2. Does the extra checkcast affect performance?

  3. 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.


  1. No, it doesn't make sense to check, as null is always castable to any reference type. 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.
  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. It's an opportunity for improvement, but nothing that will break in any case.


It might be related to a known bug in javac: Unnecessary checkcast in generated code.

0

精彩评论

暂无评论...
验证码 换一张
取 消