Нелегальный рефлексивный доступ на потоках с использованием рефлексии
Я использую рефлексию для вызова методов на java.util.stream.Stream, но поскольку фактические реализации (ReferencePipeline и т. Д.) Имеют реальный код, который выполняется, я получаю недопустимые рефлексивные предупреждения о доступе при вызове method.setAccessible(true)
и без этого звонка это не сработает. Мне было интересно, есть ли способ автоматически делегировать это супер-метод, где доступ не является незаконным? То есть я хочу позвонить filter
где это разрешено java.util.stream.Stream
и не ReferencePipeline
или что бы реализация не была.
РЕДАКТИРОВАТЬ Вот некоторый код. target
является конкретным примером потока, полученного с помощью отражения.
assert target instanceof java.util.stream.Stream;
Method candidate = Stream.of(target.getClass().getMethods())
.filter(method -> method.getName().equals("filter"))
//.filter(myComplicatedCriteria) - omitted for brevity
.findAny().orElseThrow();
try {
candidate.setAccessible(true);
return candidate.invoke(target, candidateParameterValues);
}
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new EolRuntimeException(ex);
}
1 ответ
Используйте класс интерфейса Stream
вместо реализующего класса target.getClass()
, Измените код на:
Method candidate = Stream.of(Stream.class.getMethods())
.filter(method -> method.getName().equals("filter"))
...
Основная причина проблемы java.util.stream.ReferencePipeline
так же как java.util.stream.ReferencePipeline.Head
быть защищенным пакетом. Ваш класс не может получить доступ к этим классам, используя отражение, даже если filter()
Сам метод определяется как public
,
Stream.class.getMethods()
подход будет работать, потому что ваш класс может получить доступ к общественности Stream
учебный класс. Увидеть sun.reflect.Reflection.ensureMemberAccess()
проверьте, если вам нужны детали.