Una excepción lanzada desde un intialiser estática puede indicar un problema de diseño. Realmente no deberías intentar cargar archivos en statics. También estático no debe, en general, ser mutable.
Por ejemplo, trabajando con JUnit 3.8.1 casi podría usarlo desde un applet/WebStart, pero falló debido a que un inicializador estático realizaba acceso a archivos. El resto de la clase involucrada se ajustó al contexto, es solo esta parte de la estática lo que no encajó en el contexto y destruyó todo el marco.
Existen casos legítimos en los que se produce una excepción. Si se trata de un caso en el que el entorno no tiene una característica en particular, por ejemplo, porque es un JDK antiguo, entonces es posible que desee sustituir las implementaciones, y no hay nada fuera de lo común. Si la clase realmente tiene borked, ejecute una excepción sin marcar en lugar de permitir que exista una clase rota.
Dependiendo de su preferencia y el problema en cuestión, hay dos formas comunes de evitarlo: un inicializador estático explícito y un método estático. (I, y creo que la mayoría de la gente, prefiero la primera, creo Josh Bloch prefiere este último.)
private static final Thing thing;
static {
try {
thing = new Thing();
} catch (CheckedThingException exc) {
throw new Error(exc);
}
}
O
private static final Thing thing = newThing();
private static Thing newThing() {
try {
return new Thing();
} catch (CheckedThingException exc) {
throw new Error(exc);
}
}
Nota: la estática deben ser definitiva (y generalmente inmutables). Al ser final, la correcta asignación individual es verificada por su amigable compilador. La asignación definitiva significa que puede detectar el manejo de excepciones interrumpidas: envolver y arrojar, no imprimir/registrar. Extrañamente, no se puede usar el nombre de la clase para calificar la inicialización con el nombre de la clase en el inicializador estático (estoy seguro de que hay una buena razón para esto).
Los inicializadores de instancia son similares, aunque puede hacer que el constructor lance o puede colocar el inicializador dentro del constructor.
La respuesta de akf es correcta, pero si odias declarar nuevos métodos, también puedes usar bloques estáticos para inicializar tus variables estáticas; puedes tener try/catch dentro de bloques estáticos. –
Para que otros no lean mi último comentario como una aprobación del enfoque de bloqueo estático: prefiero crear nuevos métodos. Solo sugerí una alternativa para aquellos que no lo hacen. :-) –
Lo siento, olvidé marcar el campo como estático. ¿La recomendación todavía se aplica? – kpozin