Рассмотрим следующий фрагмент Java:
public class Test {
public static void use(Object[] x) {
}
public static void main(String[] args) {
Object[] x = null;
use(x);
}
}
Байт-код Java, созданный для main()
компилятором Eclipse 3.7, выглядит следующим образом:
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
. Похоже, что он делает это только для массивов, а не для любых других типов переменных.
Мои вопросы:
Насколько я знаю, null
присваивается любому классу, включая массивы. Имеет ли смысл любой для checkcast
известного null
значения?
Влияет ли дополнительная checkcast
на производительность?
Может ли это быть ошибкой в компиляторе Eclipse Java?
Примечание:
Я могу частично ответить (2), по крайней мере, что касается JVM OpenJDK 1.6.0b22. Я выполнил простой тест с несколькими заданиями для null
в сжатые сроки. Я не смог обнаружить никакой постоянной разницы в производительности, так или иначе.
Тем не менее, мой тест был достаточно простым, так что любой полуприличный оптимизатор, вероятно, сделал бы его бесполезным, поэтому он не может быть показателем реального приложения. Я ожидаю, что JVM будет всегда оптимизировать этот checkcast
код операции, но это может быть не так.