简体   繁体   English

如何在java中重新定义lambda匿名类

[英]How to redefine lambda anonymous class in java

JDK8 convert lambda expressions to anonymous class in JDK8将lambda表达式转换为匿名类

InnerClassLambdaMetafactory.spinInnerClass() {
    return UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
}

I'm writing a javaagent, use asm to modify classBytes (add a method) and pass it to defineAnonymousClass , but the method end up with a ClassNotFoundException of this anonymous class. 我正在编写一个javaagent,使用asm来修改classBytes (添加一个方法)并将其传递给defineAnonymousClass ,但该方法最终会得到这个匿名类的ClassNotFoundException。 is there any way I can modify the content of annonymous classBytes? 有什么方法可以修改匿名classBytes的内容吗?

Transforming anonymously loaded classes is tricky. 转换匿名加载的类很棘手。 Are you retranforming already loaded classes that represent such classes? 您是否重新构建已经加载的代表此类的类? If so, watch out that Class::getName does not return the actual binary name of the class but adds a random hash such as my.DefinedType/12345 where you would need to strip the latest numbers. 如果是这样,请注意Class::getName不会返回类的实际二进制名称,但会添加一个随机哈希,例如my.DefinedType/12345 ,您需要删除最新的数字。

Also, you cannot reference such classes directly from another class but you need to reference them directly from either the reflection API or ideally a method handle. 此外,您不能直接从另一个类引用这些类,但您需要直接从反射API或理想情况下的方法句柄引用它们。 You cannot look up such classes from a class loader which is why they are called anonymous. 你不能从类加载器中查找这些类,这就是它们被称为匿名的原因。

Finally, when installing a class file transformer, the loading of such anonymous classes is not registered with the transformer. 最后,在安装类文件转换器时,不会在变换器中注册此类匿名类的加载。 The easiest way of dealing with such classes is to patch the lambda meta factory that is responsible for creating lambda types. 处理这些类的最简单方法是修补负责创建lambda类型的lambda元工厂。 You can do so easily by using for example Byte Buddy which allows you to create an agent: 您可以使用例如Byte Buddy轻松完成此操作,它允许您创建代理:

new AgentBuilder.Default()
  .with(LambdaTransformationStrategy.ENABLED)
  .type(someMatcher)
  .transform(someTransformer)
  .installOn(instrumentation);

Calling this, under the covers, Byte Buddy rewrites the JVM's default lambda meta factory class and replaces it with its own code generation where such instrumentation is possible. 调用此功能,Byte Buddy重写了JVM的默认lambda元工厂类,并将其替换为自己的代码生成,可以进行此类检测。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM