Java Concurrency in Practice de Goetz, página 41, menciona cómo puede escaparse la referencia this
durante la construcción. A "no hacer esto" ejemplo:¿Qué es un "objeto incompletamente construido"?
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
}
}
Aquí this
está "escapando" a través del hecho de que doSomething(e)
se refiere a la ThisEscape
ejemplo que encierra. La situación se puede solucionar utilizando métodos de fábrica estáticos (primero construye el objeto simple, luego registra al oyente) en lugar de los constructores públicos (haciendo todo el trabajo). El libro continúa:
La publicación de un objeto desde dentro de su constructor puede publicar un objeto incompletamente construido. Esto es verdadero incluso si la publicación es la última declaración en el constructor. Si se escapa la referencia
this
durante la construcción, el objeto se considera no construido correctamente.
No me sale esto. Si la publicación es la última declaración en el constructor, ¿no se ha realizado todo el trabajo de construcción antes de eso? ¿Cómo es que this
no es válido para entonces? Aparentemente hay algo de vudú después de eso, ¿pero qué?
¡Guau, es sorprendente que los campos 'finales', que generalmente se consideran favorables a la concurrencia, sean los culpables en este caso! –
@Joonas: ese es el problema: son compatibles con la concurrencia * si se asegura de que la referencia no escapa del constructor *. En la mayoría de los casos, es un precio bastante bajo para pagar. –
En realidad, esto se aplica a cualquier campo, no solo a los campos finales. –