Intereting Posts
Как управлять страницами ViewPages с другой страницы Как я могу запросить виброзвонок? Glide – добавление заголовка для запроса Обновление системного приложения Android с / без подписи на платформе Android Keystore – может ли пользовательский ключ извлекаться root, если он настроен для этого пользователя? Как обновить файлы с файлами (js css images) в приложении Android-телефона Android без обновления моего приложения в магазине Play / App Store Ошибка при переходе от страницы с картой на Android, в то время как экранная клавиатура видна Компиляция ffmpeg с помощью android ndk r5b Как создать файлы .docx и .xlsx на Android Как отключить закрытие панели уведомлений после нажатия на собственное уведомление Как получить уникальный идентификатор пользователя One Signal в Mobile? Android Picasso – Как получить статистику по просмотрам и загрузке кеша StartActivity в подклассе приложения Наберите номер без подсказки Использование javaagent с Android

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