Я использую отражение для вызова методов в java.util.stream.Stream, но поскольку фактические реализации (ReferencePipeline и т. д.) Имеют фактический исполняемый код, я получаю предупреждения о незаконном отражении доступа при вызове method.setAccessible(true), а без этого вызова он не работает. не работает. Мне было интересно, есть ли способ автоматически делегировать это супер-методу, доступ к которому не является незаконным? То есть я хочу вызвать filter там, где это разрешено для java.util.stream.Stream, а не ReferencePipeline или какой-либо другой реализации.
ИЗМЕНИТЬ Вот код. target - это конкретный экземпляр Stream, полученный посредством отражения.
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);
}
Минимальный пример потребует слишком много кода, поскольку он отражает. Проблема в том, что я вызываю предположительно совершенно законный метод (например, filter), но поскольку экземпляр, в котором он вызывается, является подклассом Stream, невозможно убедить Java, что я пытаюсь использовать «легальный» метод.
Переопределенный метод не может ограничить видимость супер-метода. Скорее всего, вы пытаетесь получить доступ к перегруженному методу в дочернем классе. Невозможно узнать, что происходит, так как вы не хотите предоставлять код :(
Неужто должно быть что-то, что можно сделать с MethodHandles?




Используйте класс интерфейса 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(), если вам нужны подробности.
Не могли бы вы предоставить код, чтобы проиллюстрировать проблему?