为什么此代码会导致 "this reference" 隐式转义?
Why does this code cause "this reference" to escape implicitly?
“当内部 EventListener 实例发布时,封闭的 ThisEscape 实例也发布”是什么意思。意思是?
此引自《java 并发实践》
public class ThisEscape {
public ThisEscape(EventSource source)
{
source.registerListener(
new EventListener(){
public void onEvent(Event e)
{
doSomething(e);
}
}
);
}
}
ThisEscape
实例是在构建时发布的,因为 doSomething
是 ThisEscape
的方法,可能会导致无法预料的问题。
一个简单的代码示例,当一个事件发生时,ThisEscape
对象还没有被构建,但是由于这个ThisEscape
注册到了EventSource
,那么onSomeThing
方法被触发,由于ThisEscape#data
还没有初始化,所以生成了一个NPE
:
public class ThisEscape {
static class EventSource {
private List<EventListener> eventListeners = new ArrayList<>();
public void registerListener(EventListener eventListener) {
eventListeners.add(eventListener);
}
public void eventHappen(Event event) {
eventListeners.forEach(eventListener -> {
eventListener.onEvent(event);
});
}
}
static class Event {
public String eventString;
public Event(String eventString) {
this.eventString = eventString;
}
}
interface EventListener {
void onEvent(Event e);
}
private List<String> data;
public void doSomething(Event e) {
data.add(e.eventString);
}
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
}
);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.data = new ArrayList<>();
}
public static void main(String[] args) {
EventSource eventSource = new EventSource();
new Thread(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
eventSource.eventHappen(new Event("hello"));
}).start();
ThisEscape thisEscape = new ThisEscape(eventSource);
}
}
“当内部 EventListener 实例发布时,封闭的 ThisEscape 实例也发布”是什么意思。意思是?
此引自《java 并发实践》
public class ThisEscape {
public ThisEscape(EventSource source)
{
source.registerListener(
new EventListener(){
public void onEvent(Event e)
{
doSomething(e);
}
}
);
}
}
ThisEscape
实例是在构建时发布的,因为 doSomething
是 ThisEscape
的方法,可能会导致无法预料的问题。
一个简单的代码示例,当一个事件发生时,ThisEscape
对象还没有被构建,但是由于这个ThisEscape
注册到了EventSource
,那么onSomeThing
方法被触发,由于ThisEscape#data
还没有初始化,所以生成了一个NPE
:
public class ThisEscape {
static class EventSource {
private List<EventListener> eventListeners = new ArrayList<>();
public void registerListener(EventListener eventListener) {
eventListeners.add(eventListener);
}
public void eventHappen(Event event) {
eventListeners.forEach(eventListener -> {
eventListener.onEvent(event);
});
}
}
static class Event {
public String eventString;
public Event(String eventString) {
this.eventString = eventString;
}
}
interface EventListener {
void onEvent(Event e);
}
private List<String> data;
public void doSomething(Event e) {
data.add(e.eventString);
}
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
}
);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.data = new ArrayList<>();
}
public static void main(String[] args) {
EventSource eventSource = new EventSource();
new Thread(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
eventSource.eventHappen(new Event("hello"));
}).start();
ThisEscape thisEscape = new ThisEscape(eventSource);
}
}