Почему компилятор Java Eclipse проверяет приведение типов с нуля? - PullRequest
2 голосов
/ 28 сентября 2011

Рассмотрим следующий фрагмент 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. Похоже, что он делает это только для массивов, а не для любых других типов переменных.

Мои вопросы:

  1. Насколько я знаю, null присваивается любому классу, включая массивы. Имеет ли смысл любой для checkcast известного null значения?

  2. Влияет ли дополнительная checkcast на производительность?

  3. Может ли это быть ошибкой в ​​компиляторе Eclipse Java?

Примечание:

Я могу частично ответить (2), по крайней мере, что касается JVM OpenJDK 1.6.0b22. Я выполнил простой тест с несколькими заданиями для null в сжатые сроки. Я не смог обнаружить никакой постоянной разницы в производительности, так или иначе.

Тем не менее, мой тест был достаточно простым, так что любой полуприличный оптимизатор, вероятно, сделал бы его бесполезным, поэтому он не может быть показателем реального приложения. Я ожидаю, что JVM будет всегда оптимизировать этот checkcast код операции, но это может быть не так.

Ответы [ 3 ]

2 голосов
/ 28 сентября 2011
  1. Нет, проверять не имеет смысла, так как null всегда можно преобразовать к любому ссылочному типу.Но это ничего не повредит.
  2. Любой приличный JIT в любом случае оптимизирует проверку (это фактически бездействие), поэтому самая большая стоимость - это три байта, которые занимает инструкция.
  3. Я бы не стал считать это «ошибкой», так как сгенерированный байт-код работает должным образом - он никогда не вызовет ClassCastException, так как значение всегда известно и правильно - и, как вы, очевидно, видели, естьне реальная разница в производительности в любом случае.Это возможность для улучшения, но ничего, что не сломит 1009 * в любом случае.
2 голосов
/ 28 сентября 2011

Что касается вашего первого вопроса, вы правы, инструкция по проверке чека там избыточна.Согласно Sun Wotspot Java Wiki нулевые проверки и проверки экземпляров дешевы.

Я открыл проблему в Eclipse Bugzilla , чтобы получить отзыв от команды компилятора Eclipse, нокак было указано ранее, это избыточная, но безвредная проверка.Это влияет только на размер байт-кода, и компилятор Java HotSpot, вероятно, применит оптимизацию проверки типа во время выполнения.

Обновление: от команды компилятора Eclipse это выглядит как побочный эффект другого старогоошибка .

0 голосов
/ 28 сентября 2011

Это может быть связано с известной ошибкой в ​​javac: Ненужная проверка в сгенерированном коде .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...