При условии, что появилась JPMS (Java Platform Module System), некоторые виды поведения платформы претерпели изменения. Можно привести в качестве примера использования отражения. Перед модулей, с Reflection API, можно было сломать инкапсуляцию объектов и доступ к их атрибуты частные. С JPMS это поведение изменилось, и теперь разработчик должен настроить модуль, чтобы позволить отражение, в противном случае будет сгенерировано исключение. Есть некоторые детали, за этой конфигурации, и идея использовать их во время поста.
Vale destacar que, mismo nas versace em que existe pas (9+), мудрая цитата acima só ocorrera se estiver compilando com путь к модулю .
Есть два способа, чтобы разрешить отражение. Первая из них-это использование зарезервированного слова open в объявлении модуля, таким образом, будет разрешено использовать reflection для всех пакетов.
open module br.com.exemplo {
}
Другой вариант, позволяющий отражение в пакет, для этого мы используем зарезервированное слово opens декларации пакета.
module br.com.exemplo {
opens br.com.exemplo.modelo;
}
Любая попытка использовать отражение в пакете, который не является br.с.пример.модель приведет к исключению. Последний вариант по-прежнему позволяет использовать opens декларативный, то есть, о том, какой конкретный модуль может выполнять отражение в пакет. Мы можем сделать это, используя слово to
module br.com.exemplo {
opens br.com.exemplo.modelo to br.com.outroexemplo.dao;
}
Таким образом, мы говорим, что только модуль br.с.outroexemplo.dao вы можете использовать отражение в пакет вы можете использовать отражение в пакет
Мы будем использовать Основной класс модуля br.с.главная для того, чтобы сделать доступ отражающей в классе Человек модуля br.с.модель .
package br.com.principal;
import java.lang.reflect.Field;
import br.com.modelo.Pessoa;
class Principal {
public static void main(String[] args) throws NoSuchFieldException {
Field f = Pessoa.class.getDeclaredField("peso");
f.setAccessible(true);
}
}
Класс Человек имеет только один атрибут частная.
package br.com.modelo;
public class Pessoa {
private Double peso;
}
Модуль br.с.модель экспортирует пакет с класс Человек
module br.com.modelo {
exports br.com.modelo;
}
Модуль br.с.главная , делает requires модуль br.с.модель
module br.com.principal {
requires br.com.modelo;
}
Мы можем скомпилировать проект с javac -d mods --module-source-path src -м br.с.главная и если не дала никаких проблем, мы используем java --module-path mods-м br.с.главная/br.с.главная.Главная для запуска программы. Как не устанавливаем наши модули, чтобы разрешить отражения, вывод заключается в следующем:
Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field private java.lang.Double br.com.modelo.Pessoa.peso accessible: module br.com.modelo does not "opens br.com.modelo" to module br.com.principal
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:176)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:170)
at br.com.principal/br.com.principal.Principal.main(Principal.java:9)
Чтобы изменить это поведение, просто получить помощь при изменении в module-info.java модуля br.с.модель , где-модуль br.с.главная может иметь светоотражающий в ваш пакет.
Здесь действительны все правила, указанные на введение пост.
module br.com.modelo {
exports br.com.modelo;
opens br.com.modelo to br.com.principal;
}
Если скомпилировать и запустить снова, мы увидим, что не появляется больше исключение, и мы можем использовать отражение.
Проверка, если позволяет отражения, делается по методу setAccessible . Он является метод caller sensitive и его характеристика работать по-разному в зависимости от того, кто вызывает. Когда класс или модуль, нужно использовать отражение в другой модуль, проверяется, есть ли зарезервированное слово open или opens в модуле назначения. Если у вас есть, это делается успешно, в противном случае результат является исключением. Чтобы узнать, когда метод caller sensitive , просто поиск по аннотации @CallerSensitive .
Мы видели, что, с JPMS, наши классы находятся более защищенным, обеспечивая более инкапсуляции. В случае необходимости использования reflection, наша задача-выполнить настройки в модулях. Все это поведение обеспечивается методом caller sensitive , который проверяет, есть ли модуль или класс, “вызывающей” имеет разрешение на доступ светоотражающий модуль назначения. Идея была показать немного этих деталях, и я надеюсь, что достигнуто, но если остались какие-либо вопросы, оставьте свой комментарий здесь или в моих социальных сетей, что буду в распоряжении. Спасибо! =)
Оригинал: “https://dev.to/j_a_o_v_c_t_r/reflection-com-jpms-4lk4”