阅读关于JSR-133的this article,它说:
对最终字段的所有写入(以及可到达的变量) 间接地通过那些最终的领域)变得“冷冻”,#34; ...
如果在施工期间不允许物体的参考物逃逸, 一旦构造函数完成并且一个线程发布了一个 引用一个对象,保证该对象的最终字段 可见......
初始化安全性的一个警告是对象的问题 参考不得"逃避"它的构造函数 - 构造函数应该 不直接或间接地发布对象的引用 构造
我的问题是关于什么被认为是逃避。更具体地说,我想知道这个(有点人为和奇怪的)代码是否会产生一个安全可发布的Child对象:
class Parent {
/** NOT final. */
private int answer;
public int getAnswer() {
return answer;
}
public void setAnswer(final int _answer) {
answer = _answer;
}
}
public class Child extends Parent {
private final Object self;
public Child() {
super.setAnswer(42);
self = this;
}
@Override
public void setAnswer(final int _answer) {
throw new UnsupportedOperationException();
}
}
所以,Child"是否可以安全地发布",如果不是,为什么,并且会自我get"改变答案?
如果问题的目的不明确,我认为如果这样做,它将允许一个人轻松地制作一个可变的类"安全可发布",只需将其扩展为如上所示。
答案 0 :(得分:4)
你可能误解了逃避的意义。关键是this
的值不能到达构造函数的任何外部代码。我想一些例子可以更好地解释它:
this
并不算作转义; this
分配给异物的变量,不算作转义; this
的公开,可覆盖的方法计算为转义,除非该类为final
。因此,当您致电this
时,您的代码可以setAnswer
转义,而不是在this
转让给self
时。为什么?因为子类可能会覆盖此方法并将this
发布到任何外部代码。有关self
:self
的推理的说明可以从this
到达,这并不取决于外国来电者无法获得其价值的事实。方法可以在内部取消引用它就足够了。无论如何,关于冻结的规则没有考虑变量的访问级别。例如,一切都可以通过反射来获得。