是的,即使从未真正使用匿名内部类的实例,也保留对其封闭实例的引用。这段代码:
public class Outer { public Runnable getRunnable() { return new Runnable() { public void run() { System.out.println("hello"); } }; }}
使用编译时,会
javac生成两个类文件,
Outer.class和
Outer.class。使用
javap -cyield
分解后者,即匿名内部类:
Compiled from "Outer.java"class Outer extends java.lang.Object implements java.lang.Runnable{final Outer thisputfield;Outer(Outer); Code: 0: aload_0 1: aload_1 2: putfield #1; //Field thisthis:LOuter; 5: aload_0 6: invokespecial #2; //Method java/lang/Object."<init>":()V 9: returnpublic void run(); Code: 0: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #4; //String hello 5: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return}Outer
该行显示构造函数将对封闭实例的引用存储在(类型为)的字段中,即使此字段不再使用。
如果尝试使用匿名内部类创建小的可能长期存在的对象,这将是不幸的,因为它们将保留(可能很大)封闭的实例。解决方法是改用静态类(或顶级类)的实例。不幸的是,这更加冗长。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)