当前位置: 首页 > 知识库问答 >
问题:

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

宋伟泽
2023-03-14

我正在使用反射来调用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个答案

储思聪
2023-03-14

使用接口类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()检查。

 类似资料:
  • JDK11+spring批处理 有人知道那些警告是什么意思吗: 警告:发生了非法的反射访问操作警告:org.springframework.cglib.core.reflectutils$1(jar:file:/users/boru/downloads/spcljr/build/libs/spcljr-0.0.1-snapshot.jar!/boot-inf/lib/spring-core-5.0

  • 在Java9中有很多关于非法反射访问的问题。 我发现了很多关于如何处理错误消息的讨论,但我想知道非法反射访问实际上是什么。 所以我的问题是: 我认为这与Java9中引入的封装原则有关,但我找不到一个解释,说明它们是如何联系在一起的,是什么触发了警告,以及在什么场景中。

  • 问题内容: 我一直在尝试找出能做什么或可能有什么好处,但同时我想知道是否可以通过反射投射对象。 首先,我认为以下几行可能会错误地起作用: 但是,如果没有显式强制转换,它将无法正常工作。 那么什么是上课方法呢?并且仅通过反射来投射对象是否有可能,因此您找到了该对象的类,对其进行使用并以某种方式对其进行了投射? 问题答案: 一个有效的示例: 这使您可以编写: 您的代码不起作用的原因是Class.for

  • 最近升级到Java11并开始执行回归检查。当前在尝试调用时出现非法反射访问错误。目前在Itext版本5.5.13上,但也在Itext 7.0.0上试用过,出现了相同的问题。 有人对如何修复Java-11和iText之间的兼容性问题有什么建议吗? 警告:发生了非法反射访问操作警告:com.itextpdf.io.source.ByteBufferRandomAccessSource$1(文件:...

  • 我正在为AmazonMQ编写一个简单的Java JMS QueueBrowser客户端,它通过< code>ssh运行带有< code>stomp协议的ActiveMQ(因此传输是< code>stomp ssl: 由于所使用的传输方式,我得到了一个< code > javax . JMS . JMS exception exec epion(我假设是< code>stomp ssl) Activ