给出以下代码:
public interface Selectable {
public void select();
}
public class Container implements Selectable {
public void select() {
...
}
public void createAnonymousClass() {
Selectable s = new Selectable() {
public void select() {
//see comment below.
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
我想Container.select()从我的匿名类' select()方法中访问.但是,this.select()会再次调用匿名类的select()方法.
我的建议是:
在Container中引入一个字段,例如
private Container self = this;
Run Code Online (Sandbox Code Playgroud)
现在我可以Container.select()通过self.select()在匿名类中调用来访问.
这是一种合理的方式吗?还是有更好的方法吗?
我非常感谢帮助理解"Java Concurrency in Practice"中的以下内容:
从构造函数中调用可重写的实例方法(既不是私有也不是最终的)也可以允许此引用转义.
之前的问题略有不同,但要求是/否答案,但我正在寻找书中遗漏的解释(Java Concurrency in Practice),这个明显的大错误将如何被恶意或意外地利用.
可以发布对象或其内部状态的最终机制是发布内部类实例,如清单3.7中的ThisEscape所示.当ThisEscape发布EventListener时,它也隐式发布封闭的ThisEscape实例,因为内部类实例包含对封闭实例的隐藏引用.
清单3.7.隐式允许此引用转义.不要这样做.
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
3.2.1.安全施工实践
ThisEscape说明了一个重要的特殊情况 - 当它在构造过程中引用逃逸时.发布内部EventListener实例时,封闭的ThisEscape实例也是如此.但是只有在构造函数返回后,对象才处于可预测的一致状态,因此从构造函数中发布对象可以发布未完全构造的对象.即使发布是构造函数中的最后一个语句,也是如此.如果此参考在施工期间逃逸,则认为该物体构造不正确.[8]
[8]更具体地说,在构造函数返回之前,此引用不应从线程中转义.这个引用可以由构造函数存储在某处,只要它在构造之后不被另一个线程使用.清单3.8中的SafeListener使用了这种技术.
在施工期间不要让此参考物逃逸.
在完成构建之前,有人会如何编写代码以进入OuterClass?hidden inner class reference第一段用斜体字提到的是什么?