Cómo manejar un inicializador de campo final estático que lanza una excepción marcada


Me enfrento a un caso de uso en el que me gustaría declarar un campo static final con una instrucción initializer que se declara para lanzar una excepción marcada. Por lo general, se vería así:

public static final ObjectName OBJECT_NAME = new ObjectName("foo:type=bar");

El problema que tengo aquí es que el constructor ObjectName puede lanzar varias excepciones verificadas, lo que no me importa (porque sabría que mi nombre es válido, y está bien si se bloquea miserablemente en caso de que no lo sea). El compilador de Java no me dejará ignorar esto (ya que es una excepción marcada), y preferiría no recurrir a:

public static final ObjectName OBJECT_NAME;
static{
    try{
        OBJECT_NAME = new ObjectName("foo:type=bar");
    }catch(final Exception ex){
        throw new RuntimeException("Failed to create ObjectName instance in static block.",ex);
    }  
}

Porque los bloques estáticos son muy, muy difíciles de leer. ¿Alguien tiene alguna sugerencia sobre cómo manejar este caso de una manera agradable y limpia?

Author: Romain, 2009-12-08

3 answers

Si no te gustan los bloques estáticos (algunas personas no), entonces una alternativa es usar un método estático. IIRC, Josh Bloch recomendó esto (aparentemente no en Java Eficaz en la inspección rápida).

public static final ObjectName OBJECT_NAME = createObjectName("foo:type=bar");

private static ObjectName createObjectName(final String name) {
    try {
        return new ObjectName(name);
    } catch (final SomeException exc) {
        throw new Error(exc);
    }  
}

O:

public static final ObjectName OBJECT_NAME = createObjectName();

private static ObjectName createObjectName() {
    try {
        return new ObjectName("foo:type=bar");
    } catch (final SomeException exc) {
        throw new Error(exc);
    }  
}

(Editado: Corregido el segundo ejemplo para volver del método en lugar de asignar el static.)

 43
Author: Tom Hawtin - tackline,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-19 17:26:59

Su código es perfectamente válido. No me resulta difícil leer. Otras formas solo lo harían peor. Solo son difíciles de leer para empezar, porque la mayoría de ellos no están familiarizados con eso. Simplemente siga las convenciones estándar con respecto al orden de los elementos en el código. Por ejemplo, no ponga inicializadores estáticos a mitad de camino o en la parte inferior completa del código y tampoco tenga varios de ellos extendiéndose sobre la clase. Solo pon uno en la parte superior, después de declaraciones estáticas.

 16
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-08 13:08:23

static los bloques no son difíciles de leer. Así que recomendaría esa solución. Sin embargo, puede envolver su objeto en otro objeto, por ejemplo ObjectNameWrapper que comparte un interface con su ObjectName, y cuyo constructor llama a su constructor ObjectName, ocultando todas las excepciones marcadas que ocurren. Pero de nuevo, yo iría por la opción estática.

 5
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-08 13:09:59