阅读有关JSR-133的这篇文章,它说:
所有对最终字段的写入(以及通过这些最终字段间接到达的变量)都会变为"冻结",......
如果在构造期间不允许对象的引用转义,那么一旦构造函数完成并且线程发布对对象的引用,该对象的最终字段将保证可见...
初始化安全性的一个警告是,对象的引用不得"转义"其构造函数 - 构造函数不应直接或间接地发布对正在构造的对象的引用.
我的问题是关于什么被认为是逃避.更具体地说,我想知道这个(有点人为和奇怪的)代码是否会产生一个安全可发布的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();
}
}
Run Code Online (Sandbox Code Playgroud)
那么,儿童是"安全可发布的",如果没有,为什么,并且"自我"的吸气者会改变答案吗?
如果问题的目的不明确,我认为如果这有效,它将允许人们轻松地将一个可变类"安全地发布",只需如上所示扩展它.
您可能误解了逃避的含义。要点是 的值this不得到达构造函数之外的任何代码。我认为几个例子可以更好地解释它:
this不算作转义;this给外部对象的变量,不算作转义;this 确实算作转义,除非该类是final。因此,您的代码会this在您调用时进行转义setAnswer,而不是在您分配给时进行this转义self。为什么?因为子类可能会重写此方法并发布this到任何外部代码。self关于您关于:的推理的注释self是可以访问的this,这并不取决于外国调用者无法获取其值的事实。一个方法可以在内部取消引用它就足够了。无论如何,关于冻结的规则没有考虑变量的访问级别。例如,一切都可以通过反射到达。
| 归档时间: |
|
| 查看次数: |
121 次 |
| 最近记录: |