Нелегальный рефлексивный доступ на потоках с использованием рефлексии

Я использую рефлексию для вызова методов на 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() проверьте, если вам нужны детали.

Другие вопросы по тегам