java – MethodHandles.lookup().defineClass retention
发布时间:2020-12-15 00:56:30 所属栏目:Java 来源:网络整理
导读:MethodHandles.Lookup.defineClass 在运行时从字节数组生成一个新类. 在什么情况下返回的类可以被垃圾收集?是否在与Lookup对象关联的类加载器的生命周期内保留,或者如果不再引用Class对象,它是否可以进行垃圾回收? 解决方法 通过MethodHandles.Lookup.defi
MethodHandles.Lookup.defineClass 在运行时从字节数组生成一个新类.
在什么情况下返回的类可以被垃圾收集?是否在与Lookup对象关联的类加载器的生命周期内保留,或者如果不再引用Class对象,它是否可以进行垃圾回收? 解决方法
通过MethodHandles.Lookup.defineClass创建的类与任何其他类一样在定义类加载器中注册,并且可以像普通类一样通过名称引用.在解析这些类之前,它们甚至可以取代静态编译的类,如下例所示:
import java.lang.invoke.MethodHandles; import java.nio.charset.StandardCharsets; public class LookupDynamicClass { public static void main(String[] args) throws IllegalAccessException { MethodHandles.Lookup lookup = MethodHandles.lookup(); lookup.defineClass(("êto? 005 2611 11 1210 1312 14 " +"157 167 171 3foo1 3()V1 4Code7 2014 21 221 " +"30hello from dynamic class7 2314 24 251 4Lazy1 20java/" +"lang/Object1 20java/lang/System1 3out1 25Ljava/io/PrintStream;" +"1 23java/io/PrintStream1 7println1 25(Ljava/lang/String;)V6 " +" 4 5 1 11 6 7 1 10 25 2 112 " + "1222? 3± ").getBytes(StandardCharsets.ISO_8859_1)); Lazy.foo(); } } interface Lazy { static void foo() { } } Try it online 此示例动态定义一个Lazy类,其foo()方法将在调用时从动态类中打印hello. 在像HotSpot这样的JVM上,符号引用“Lazy”被懒散地解析,即在尝试调用Lazy.foo()时,这将最终在动态定义的类中.对于急切解析符号引用的JVM,当调用MethodHandles.Lookup.defineClass时,Lazy类已经存在,因此,将抛出带有“尝试重复定义Lazy”之类的消息的LinkageError. 换句话说,这些动态生成的类与静态编译的类共享相同的名称空间(类加载上下文).像普通类一样在类加载器中注册,只有在定义类加载器变得无法访问时(包括所有定义的类),它们才能获得垃圾收集,就像普通类一样. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |