Intereting Posts
Вызов метода класса активности из класса обслуживания Перенос приложения Android с подпиской на другую учетную запись Время подачи заявки на приложение для Android Экран выбора уровня, например, «Башня фермы», «Злые птицы», «Отрезать веревку» и т. Д.? В приложении Android toolbar.setTitle не действует – имя приложения отображается как заголовок Как разрешить копирование и вставку с ионного веб-представления? JNI ОБНАРУЖЕН ОШИБКУ В ПРИМЕНЕНИИ Проверьте, настроена ли сеть ScanResult (существует в списке getConfiguredNetworks ()) Преобразование java-проекта в проект android на Eclipse Picasso: загружать изображения в список виджетов Почему в дизайне материалов Google говорится: «Материал никогда не сгибается и не сгибается». Управление памятью HttpClient Как изменить структуру для поддержки muti-skin? Вручную проанализировать часть ответа при использовании Retrofit Внутри OnClickListener я не могу получить доступ ко многим вещам – как подойти?

Оптимизация компилятора кода Java в Android

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

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»?

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

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

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

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


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

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

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