Перед началом основного текста этой статьи давайте посмотрим на следующий код:
Роль IntegerCache из целочисленного класса в Java
Название пакета: java.lang
Имя файла: integer.java
Имя метода: IntegerCache
Код метода заключается в следующем:
Частный статический класс IntegerCache {статический конечный int High; Статический конечный целочисленный кеш []; static {final int low = -128; // высокое значение может быть настроено Property int h = 127; if (integercachehighpropvalue! = null) {// Использование Long.decode здесь, чтобы избежать вызывания методов, которые // требуют инициализированного кэта интеллектуального размещения int i = long.decode (integercachehighpropvalue) .intvalue (); i = math.max (i, 127); // максимальный размер массива IS Integer.max_value h = math.min (i, integer.max_value - -low); } high = h; cache = new Integer [(High - low) + 1]; int j = низкий; for (int k = 0; k <cache.length; k ++) cache [k] = новое целое число (j ++); } private integerCache () {}}В коде мы видим, что низкий уровень -128, а высокий -127. Таким образом, в программировании Java, если вы хотите использовать объект в интервале -128-127, вы будете напрямую использовать объект в этом кэше.
Выше приведено краткое введение, чтобы помочь всем понять IntegerCache. Ниже приведен основной текст этой статьи:
введение
5 лет назад я опубликовал пост в Венгрии о том, как изменить IntegerCache в JDK. Этот подход на самом деле должен углубиться в во время выполнения Java и на самом деле не используется в сценариях. Когда вы разрабатываете этот код исследования, вы можете лучше понять, как работает рефлексия и как его реализует целочисленный класс.
В целочисленном классе есть частное вложенное именованное integercache, которое содержит целочисленные объекты со значениями в диапазоне от -127 до 128.
Когда код должен быть заключен из типа Int в целочисленный объект, а значение находится в этом диапазоне, время выполнения Java будет использовать этот кэш вместо создания нового целочисленного объекта. Это в основном для соображений оптимизации производительности. Мы должны иметь в виду, что многие значения INT часто находятся в этом диапазоне в программе (например, индекс индекса массива).
Побочный эффект этого заключается в том, что много раз при использовании оператора равных знаков для сравнения двух целочисленных объектов, если значение находится в пределах диапазона, оно действителен. Это типично в модульном тестировании. В режиме запуска, когда значение превышает 128, выполнение кода не удастся.
Используя отражение для доступа к классам IntegerCache может вызвать некоторые странные побочные эффекты, обратите внимание, что это влияет на весь JVM. Если сервлет переосмысливает небольшое значение целочисленного кеша, все остальные сервлеты, работающие под одной и той же Tomcat, сталкиваются с одной и той же проблемой.
Есть и другие статьи, выше, в Лукасе Эдере и Ситепойнте.
Теперь, когда я играю с ранними выпусками Java 9, все, что мне всегда приходилось делать в своем уме, это экспериментировать с новыми версиями Java. Прежде чем мы начнем, давайте посмотрим, как сделать это в Java 8.
В статье Лукаса я опубликовал его примеры кода здесь:
Импорт java.lang.reflect.field; import java.util.random; открытый энтропия класса {public static void main (string [] args) бросает исключение {// Извлекать IntegerCache через класс отражения <<? > clazz = class.forname ("java.lang.integer $ integercache"); Field Field = clazz.getDeclaredfield ("cache"); Field.SetAccessible (true); Integer [] cache = (integer []) field.get (clazz); // Перепишите целочисленный кэш для (int i = 0; i <cache.length; i ++) {cache [i] = new Integer (new random (). Nextint (cache.length)); } // Доказать случайность для (int i = 0; i <10; i ++) {System.out.println ((Integer) i); }}}Этот код обращается к IntegerCache через отражение, а затем использует случайные значения для заполнения кэша (Naughty!).
Мы стараемся выполнить тот же код в Java 9, не ожидайте никакого удовольствия. Когда кто -то пытается его нарушить, он обнаружит, что Java 9 более ограничивает.
Исключение в потоке "Main" java.lang.reflect.inaccessibleObjectException: невозможно сделать статический финальный финал java.lang.integer [] java.lang.integer $ integercache.cache доступным: модуль java.base не "opens java.lang".
Программа создает исключение, которое не произойдет в Java 8. Это эквивалентно сказать, что объекты не основаны на модели. Из -за модуля базы Java. Это неотъемлемая часть JDK. Он автоматически импортируется при запуске каждой Java -программы, а неназванные модули не разрешаются открывать. Это исключение брошено, когда мы пытаемся установить доступное свойство.
Объекты, к которым мы можем легко получить доступ в Java 8, теперь недоступны в Java 9, потому что новая система модуля защищает это. Код может получить доступ только к полям, методам и другой информации, к которой можно получить доступ с помощью отражения, только в том случае, если класс находится в том же модуле, или у модуля есть пакет, открытый для доступа к отражению. Это может быть реализовано через файл определения модуля модуля info.java:
модуль mymodule {exports com.javax0.module.demo; Открывает com.javax0.module.demo;} Этот модуль Java.base не обязательна, чтобы открывать ее самостоятельно для доступа к отражению, особенно для неназванных модулей. Если мы создадим модуль и назовите его, сообщение об ошибке будет содержать имя модуля.
Можем ли мы открыть модули в программе? Модуль java.lang.reflect.Module имеет метод аддопенса, который можно сделать.
Это осуществимо?
Плохая новость для разработчиков: это невозможно. Он может открыть пакет в модуле в другом модуле, и в этом модуле был открыт пакет, вызывая этот метод. Этот метод может разрешить только модули передаваться в другой модульный права, при условии, что другой модуль каким -то образом открыл один и тот же пакет и не может открыть неоткрытые пакеты (примечание переводчика: это трудно понять, не так ли?).
Но в то же время хорошие новости в том, что Java 9 не так легко взломать, как Java 8. По крайней мере, эта уязвимость закрыта. Похоже, что Java начинает развиваться на профессиональном уровне, а не просто игрушку (примечание переводчика: кто сказал, что Java - игрушка?). В ближайшем будущем вы можете очень серьезно мигрировать проекты на языках RPG и COBOL на Java. (Извините, я шутил)
Суммировать
Вышеуказанное - все содержание этой статьи. Я надеюсь, что содержание этой статьи имеет определенную справочную ценность для каждого обучения или работы. Если у вас есть какие -либо вопросы, вы можете оставить сообщение для общения. Спасибо за поддержку Wulin.com.
Эта статья переведена с: https://dzone.com/articles/hacking-the-integercache-in-java-9