¿Por qué Java no permite arrojar una excepción marcada del bloque de inicialización estática?

¿Por qué Java no permite arrojar una excepción marcada desde un bloque de inicialización estático? ¿Cuál fue el motivo de esta decisión de diseño?

Porque no es posible manejar estas excepciones comprobadas en su fuente. No tiene ningún control sobre el proceso de inicialización y no se pueden llamar bloques {} estáticos desde su origen para que pueda rodearlos con try-catch.

Debido a que no puede manejar ningún error indicado por una excepción marcada, se decidió no permitir el lanzamiento de bloques estáticos de excepciones marcadas.

El bloque estático no debe arrojar excepciones comprobadas, pero aún permite que se generen excepciones no comprobadas / runtime. Pero de acuerdo con las razones anteriores, tampoco podría manejarlos.

Para resumir, esta restricción impide (o al menos hace que sea más difícil para) que el desarrollador construya algo que puede generar errores de los cuales la aplicación no podría recuperarse.

Puede solucionar el problema detectando cualquier excepción comprobada y volviéndola a lanzar como una excepción sin marcar. Esta clase de excepción sin marcar funciona bien como un contenedor: java.lang.ExceptionInInitializerError .

Código de muestra:

 protected static class _YieldCurveConfigHelperSingleton { public static YieldCurveConfigHelper _staticInstance; static { try { _staticInstance = new YieldCurveConfigHelper(); } catch (IOException | SAXException | JAXBException e) { throw new ExceptionInInitializerError(e); } } } 

Debería verse así (esto no es código Java válido)

 // Not a valid Java Code static throws SomeCheckedException { throw new SomeCheckedException(); } 

pero, ¿cómo sería el anuncio donde lo atrapas? Las excepciones controladas requieren captura. Imagine algunos ejemplos que pueden inicializar la clase (o puede que no, porque ya está inicializada), y solo para llamar la atención sobre la complejidad de lo que introduciría, pongo los ejemplos en otro incializador estático:

 static { try { ClassA a = new ClassA(); Class clazz = Class.forName(ClassB.class); String something = ClassC.SOME_STATIC_FIELD; } catch (Exception oops) { // anybody knows which type might occur? } } 

Y otra cosa desagradable –

 interface MyInterface { final static ClassA a = new ClassA(); } 

Imagine que ClassA tenía un inicializador estático lanzando una excepción marcada: en este caso MyInterface (que es una interfaz con un inicializador estático ‘oculto’) tendría que lanzar la excepción o manejarla: ¿manejo de excepciones en una interfaz? Mejor déjalo como está.

Eche un vistazo a las especificaciones del lenguaje Java : se indica que es un error de tiempo de comstackción si el inicializador estático no se puede completar abruptamente con una excepción marcada.

Como ningún código que escriba puede invocar el bloque de inicialización estático, no es útil lanzar exceptions comprobadas. Si fuera posible, ¿qué haría el jvm cuando se lanzan las excepciones marcadas? Runtimeexceptions se propagan.

Puedo comstackr lanzando una excepción marcada también …

 static { try { throw new IOException(); } catch (Exception e) { // Do Something } }