Компилятор Java не оптимизирует статическую финальную строку. Зачем? - PullRequest
3 голосов
/ 29 января 2012

В моем приложении есть следующий код:

  public static final boolean DEBUG = true;
  public static final boolean REL = !DEBUG;

  private static final String DEBUG_OR_RELEASE = (REL) ? "RELEASE_VER" : "DEBUG_VER";

Я думал, что компилятор Java полностью исключит строку "DEBUG_VER" из полученного файла .apk (при экспорте через Proguard), но когда я проверяю файл .apk, я вижу там строку "DEBUG_VER".

Почему? Что мне не хватает? Что я сделал не так?

Ответы [ 3 ]

3 голосов
/ 29 января 2012

Компиляция в байт-код Java не оптимизирует (за исключением нескольких исключений).

Во многих книгах для упрощения говорится, что фаза «компиляции» - это когда происходит оптимизация, но это неправильно. Когда действительно происходит оптимизация, файлы байт-кода обрабатываются JVM. Так что для очистки: оптимизация может произойти во время компиляции байт-кода в машинный собственный код, что делается инструментами JVM.

Иногда оптимизация вообще отсутствует (JVM работает в режиме интерпретации). Иногда есть некоторая оптимизация, сделанная JIT (компилятор Just In Time). А иногда адаптивный оптимизатор заботится об оптимизации (не только оптимизации, но и профилировании выполнения кода в случае выполнения дополнительных операций).

Итак, наконец, в вашем файле нет ничего плохого. Так устроен мир Java.

"Но почему?" - спросите вы. Причина сохранения этой «бесполезной» информации в байт-коде заключается в том, что вы никогда не будете уверены, сколько кода вы можете удалить, чтобы оптимизация, обеспечиваемая другой JVM, могла все еще работать эффективно. Лучший способ - просто не стереть информацию и позволить оптимизаторам выполнять свою работу.

1 голос
/ 29 января 2012

Согласно тому, что вы разместили, DEBUG - это правда, поэтому REL - это ложь, поэтому (REL) ? "RELEASE_VER" : "DEBUG_VER" должно выдавать "DEBUG_VER".

Это именно то, что вы наблюдаете, поэтому, если вы ожидаете увидеть вместо этого «RELEASE_VER», вы должны установить:

public static final boolean DEBUG = false;

Попробуйте и посмотрите, что получится.

1 голос
/ 29 января 2012

Он все еще выполняется, даже если для переменной задано значение true.?: операторы являются частью исполняемого и операционного кода, и поскольку Java не имеет прекомпилятора, он будет запускаться каждый раз, когда вы компилируете.

Java не выводит и не упрощает операции автоматически, даже если логически операции одинаковы для каждой итерации.

...