2010-04-14 15 views
7

En C++, la duración de un objeto comienza cuando el constructor finaliza correctamente. Dentro del constructor, el objeto aún no existe.Excepciones en constructores

P: ¿Qué significa emitir una excepción de un constructor?

A: Significa que la construcción ha fallado, el objeto nunca existió, su vida útil nunca comenzó. [source]

Mi pregunta es: ¿Lo mismo vale para Java? ¿Qué sucede, por ejemplo, si entrego this a otro objeto y luego falla mi constructor?

Foo() 
{ 
    Bar.remember(this); 
    throw new IllegalStateException(); 
} 

¿Está bien definido? ¿Tiene Bar ahora una referencia a un objeto no?

Respuesta

8

El objeto existe, pero no se ha inicializado correctamente.

Esto puede ocurrir cuando this gotea durante la construcción (no solo cuando se lanza una excepción).

Es una situación muy problemática, porque algunas garantías comúnmente asumidas no se cumplen en esta situación (por ejemplo, los campos final podrían cambiar su valor durante la construcción).

Por lo tanto, debe evitar fugas this en el constructor.

This IBM developerWorks article describe las precauciones que hay que tomar al construir objetos y el razonamiento detrás de esas precauciones. Mientras que el artículo analiza el tema a la luz de varios subprocesos, puede tener problemas similares en un entorno de subproceso único cuando el código desconocido/no confiable recibe una referencia al this durante la construcción.

+1

+1 - pero "fugas" se denomina (insegura) "publicación" en este caso; p.ej. en Bloch. También sería una buena idea explicar esto con más profundidad. –

1

Nunca debe abrir recursos como un escritor de archivos en su constructor. Cree un método init en su lugar y hágalo desde allí. Entonces estás a salvo.

+2

* "Entonces estás a salvo" *. ¡Esa declaración es patentemente falsa! Hay ** lotes ** de otras cosas que pueden causar excepciones en un constructor; p.ej. argumento ilegal, NPE, índice de matriz, etc., e incluso errores de desbordamiento de pila o falta de memoria. –

+0

Es un buen consejo, pero hay otros casos en los que es posible que desee que falle un constructor. Por ejemplo, quiero un iterador paralelo como se describe aquí http://stackoverflow.com/questions/3137944/best-way-to-iterate-over-thwo-lists-simultaneously así que quiero comprobar que las listas sean del mismo tamaño en tiempo de construcción. –

0

Este código no es una excepción segura y tampoco sería una excepción segura en C++. Es el mismo error independientemente del idioma que use.