我正在使用一些代码,其中一个对象“ foo”创建另一个对象“
bar”,并将其传递给Callable
。此之后,foo将返回bar,然后我希望foo变得不可访问(即:可用于垃圾回收)。
我最初的想法是仅Callable
匿名创建。例如:
class Foo {
...
public Bar createBar() {
final int arg1 = ...
final int arg2 = ...
final int arg3 = ...
return new Callable<Baz>() {
@Override
public Baz call() {
return new Baz(arg1, arg2, arg3);
}
};
}
}
在我看来,这实际上可能并没有按预期方式工作,因为内部类通常会保留对其封闭对象的引用。我不想在这里引用封闭类,因为我希望在Callable
仍可访问的同时收集封闭对象。
另一方面,检测到实际上从未引用过封闭实例应该很简单,因此Java编译器可能很聪明,在这种情况下不包含引用。
那么…即使匿名内部类的实例从未真正使用过封闭实例引用,该实例仍将保留对其封闭实例的引用吗?
是的,即使从未真正使用匿名内部类的实例,也保留对其封闭实例的引用。这段代码:
public class Outer {
public Runnable getRunnable() {
return new Runnable() {
public void run() {
System.out.println("hello");
}
};
}
}
使用编译时,会javac
生成两个类文件,Outer.class
和 Outer$1.class
。使用javap -c
yield
分解后者,即匿名内部类:
Compiled from "Outer.java"
class Outer$1 extends java.lang.Object implements java.lang.Runnable{
final Outer this$0;
Outer$1(Outer);
Code:
0: aload_0
1: aload_1
2: putfield #1; //Field this$0:LOuter;
5: aload_0
6: invokespecial #2; //Method java/lang/Object."<init>":()V
9: return
public 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
}
该putfield
行显示构造函数将对封闭实例的引用存储在this$0
(类型为Outer
)的字段中,即使此字段不再使用。
如果尝试使用匿名内部类创建小的可能长期存在的对象,这将是不幸的,因为它们将保留(可能很大)封闭的实例。解决方法是改用静态类(或顶级类)的实例。不幸的是,这更加冗长。
对于这个示例: null 是否有类似这样的语句用于此检查?或者我应该使用
问题内容: 我想知道Python是否具有类似C#匿名类功能的东西。为了澄清,这是一个示例C#代码段: 在Python中,我会想象这样的事情: 特定要求是能够在表达式上下文中创建具有指定字段的对象(例如,可在lambda和不允许使用语句的其他地方使用),而无需其他外部声明,并且能够通过普通成员按名称访问各个组件访问语法。创建的对象还应按 组件名称 (而不是像元组那样按位置)实现结构比较。 特别是:元
在以下片段中: 有没有办法从内部匿名类引用匿名类的外部实例? 第二个错误是在解决方案上,我在这里找到了一个匿名内部类的外部类的关键字。这些问题似乎共享一些概念和问题空间,但性质不同。
问题内容: 如何从匿名类的方法内部访问? 问题答案: 如何从匿名类的方法内部访问? 您只需要访问它们即可: 更重要的是:为什么这对您不起作用?
问题内容: 我正在阅读Java中的匿名类,它说您可以访问封闭类的方法,但不能访问局部变量。为什么会这样呢?我在说这个: 编辑:较旧的示例是不正确的,不能反映我的意思。根据在“访问封闭类的成员”一节中所写的内容,这应该是一个更好的示例,网址为http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html。 那么这个限制解决了什
问题内容: 在ES6中,我们可以进行匿名类: 但是我们也可以实例化它: 它背后的工作是什么,它将带来什么优势以及它也会带来什么警告? 问题答案: 匿名类实例-这是一个坏主意吗? 每次评估表达式时,这种书写风格都会导致创建新的构造函数和原型对象。如果使用这种方法创建多个对象,则它们将不会获得类/原型的任何好处。 如果您打算使用此模式创建单例对象,那么您也会失败。构造函数仍然可以创建,甚至可以访问-使