java - poo - se puede instanciar una clase final
Java: ¿pueden inicializarse las variables finales en el bloque de inicialización estático? (4)
¿Puedes poner la declaración en el bloque finally?
try {
//load file
} catch(IOException e) {
// horay
} finally {
HOST=config.get......
}
Puede hacer esto pero necesita salir del bloque estático lanzando una excepción: puede volver a lanzar la excepción capturada o una nueva. En general, esta excepción debe ser una RuntimeException
. Realmente no debería atrapar una Exception
genérica sino una Exception
más específica que podría lanzarse desde dentro de su bloque de try
. Finalmente, si un inicializador estático arroja una excepción, la clase quedará inutilizable durante esa ejecución específica porque la JVM solo intentará inicializar su clase una vez. Los intentos subsiguientes de utilizar esta clase darán como resultado otra excepción, como NoClassDefFoundError
.
Entonces, para trabajar, su inicializador debería leer algo como esto:
static {
try {
...
} catch (Exception e) {
e.PrintStackTrace();
throw new InitializationFailedException("Could not init class.", e);
}
}
Suponiendo que InitializationFailedException
es una RuntimeException
personalizada, pero puede usar una existente.
Sí, por supuesto: las variables static final
se pueden inicializar en un bloque estático, pero ... tienes GOTOs implícitos en ese ejemplo ( try/catch
es esencialmente un ''GOTO catch'' si pasa algo malo '' ).
Si se lanza una excepción, sus variables final
no se inicializarán.
Tenga en cuenta que el uso de constructos estáticos va en contra del dogma orientado a objetos. Puede complicar las pruebas y hacer que la depuración sea más difícil.
public class MyClass
{
private static final SomeClass myVar;
static
{
Object obj = null; // You could use SomeClass, but I like Object so you can reuse it
try
{
obj = new SomeClass(...);
}
catch(WhateverException err)
{
// Possibly nested try-catches here if the first exception is recoverable...
// Print an error, log the error, do something with the error
throw new ExceptionInInitializerError(err);
}
finally
{
myVar = (SomeClass) obj;
}
}
}
Suponiendo que no hay aguas arriba está en condiciones de atrapar un ExceptionInInitializationError o una Excepción general, entonces el programa nunca debería intentar usar myVar . Sin embargo, si se capturan y el programa no finaliza, entonces necesitas codificar para ver y manejar myVar como nulo (o estar contento con NullPointerExceptions
por todas partes).
No estoy seguro de que haya una buena forma de manejar esto.