Оптимизация компилятора Java-кода в Android - PullRequest
4 голосов
/ 18 мая 2011

Предполагая, что я определил строку следующим образом:

private final static String s = "To Be or not to be, that is the question";

И в одном из (статических) методов я вызываю метод, который получает строку в качестве параметра:

methodThatReceivesString(s.charAt(0) + s.charAt(1) + "Inter" + s.charAt(3) + s.charAt(4))

(идея состоит в том, что methodThatReceivesString() будет передано значение "ToInterBe")

У меня такой вопрос: оптимизирует ли компилятор Java код так, чтобы скомпилированный двоичный файл (.jar .dex) уже содержал «ToInterBe»?

Или это произойдет только во время выполнения приложения?

Ответы [ 2 ]

2 голосов
/ 18 мая 2011

Компилятор Java не сделает этого, так как это технически изменит программу, поскольку используемые методы могут иметь побочные эффекты во время выполнения.Но даже если бы он предварительно вычислял строку, ему все равно нужно было бы поместить исходную строку в файл класса, так как к ней можно было бы получить доступ путем рефлексии, она могла бы иметь отношение к аннотации или по другим причинам.

Я думаю, что инструментВы ищете ProGuard .Это может, помимо прочего, фактически удалить строку, если код больше не ссылается на нее после того, как весь статически разрешимый код был предварительно вычислен.

1 голос
/ 18 мая 2011

Java-компилятору не разрешено оптимизировать это.

Проблема в том, что вызовы методов для константных объектов не определены как константные выражения;см. JLS раздел 15.28 для списка вещей, которые вы можете сделать в константном выражении.Таким образом, s.charAt(0) не является константным выражением, хотя s является константным выражением, и «мы знаем», что его значение всегда будет 'T'.Поскольку оно не является константным выражением, его нужно оценивать во время выполнения.

Если ваша цель состоит в том, чтобы предотвратить появление строки "ToInterBe" в пуле констант классов, то вы добились успеха.Но это не замедлит хорошего реверс-инженера более чем на пару минут.


(Кстати, это выражение, вероятно, не соответствует вашим ожиданиям. Первое подвыражение +является дополнением (не конкатенацией строк), поскольку ни один из операндов не является строкой. Результатом этого сложения будет int, поэтому все выражение будет иметь значение "195InterBe" ... я думаю.)

...