清单 3.7。隐式允许 this 引用转义。不要这样做。
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.7 中的 ThisEscape 所示。当 ThisEscape 发布 EventListener 时,它也会隐式发布封闭的 ThisEscape 实例,因为内部类实例类实例包含对封闭实例的隐藏引用。”
我的问题是:这个隐藏的引用在哪里以及如何利用它?
“隐藏引用”是任何非静态内部类都具有的隐式变量,允许它引用其外部类的成员。
考虑该类的一个稍微修改的版本:
public class ThisEscape {
private final List<EventSource> listOfEvents;
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
listOfEvents.add(e); //The "hidden reference" is what allows this inner class
//to use the parent's "listOfEvents" member variable
}
}
}
Thread.sleep(5000); //This would need a try/catch - skipping that
listOfEvents = new ArrayList<EventSource>();
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,很明显问题是什么 - 如果在完成EventListener之前将任何事件传递给Thread.sleep,listOfEvents则仍然为空,并且您将得到一个NullPointerException.
由于 Java 跨线程处理内存可见性的方式,即使您删除了对 的调用,sleep并且即使您将 的初始化移到了listOfEvents对registerListener!
就“利用”这一点而言,这在很大程度上取决于上下文 - 但上述模式的任何实例肯定都是可能发生的潜在错误,即使攻击者没有试图利用它。
| 归档时间: |
|
| 查看次数: |
337 次 |
| 最近记录: |