使用反射对流进行非法反射访问

时间:2018-11-14 16:49:43

标签: java reflection illegalaccessexception

我正在使用反射来调用java.util.stream.Stream上的方法,但是由于实际的实现(ReferencePipeline等)具有运行的实际代码,因此在调用method.setAccessible(true)时会收到非法的反射访问警告,没有该呼叫,它将无法正常工作。我想知道是否有一种方法可以自动将其委派给访问不非法的超级方法?也就是说,我想在filter上合法的地方调用java.util.stream.Stream,而不是ReferencePipeline上的实现方式。

EDIT这是一些代码。 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);
}

1 个答案:

答案 0 :(得分: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(),检查是否需要详细信息。