1

我正在使用反射来调用 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);
}
4

1 回答 1

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()查看是否需要详细信息。

于 2018-11-14T18:18:46.607 回答