2010-07-14 7 views
5

Tengo un colocador estático que se utiliza para configurar todas las instancias de MyClass:Java: Crear miembro de la clase estática cuyo constructor podría lanzar una excepción

public class MyClass { 
     .... 
    protected static final Setter setter = new Setter(); 
     ... 
} 

Sin embargo, esto no se compila desde el constructor colocador lanza una excepción:

public class Setter { 

    public Setter() throws FileNotFoundException { 
      .... 
    } 
} 

¿Cómo puedo evitar esto?

+0

En general, si algo arroja una excepción marcada, no es algo que desee almacenar en forma estática. –

Respuesta

17

El ExceptionInInitializerError está diseñado precisamente para este propósito. Aquí hay una cita de relevancia del Javadoc vinculado:

Señala que se ha producido una excepción inesperada en un inicializador estático. Se genera un ExceptionInInitializerError para indicar que se produjo una excepción durante la evaluación de un inicializador estático o del inicializador de una variable estática.

Envuelva la asignación en un bloque de inicializador estático y manipule en consecuencia.

public class MyClass { 
    protected static final Setter setter; 

    static { 
     try { 
      setter = new Setter(); 
     } catch (FileNotFoundException e) { 
      throw new ExceptionInInitializerError(e); 
     } 
    } 
} 
2

Puede crearlo dentro de una función estática, siempre que detecte la excepción que (potencialmente) plantea.

public class MyClass { 
    protected static final Setter setter = createSetter(); 

    protected static Setter createSetter() { 
     try { 
      return new Setter(); 
     } catch(FileNotFoundException e) { 
      // handle it appropriately 
      return null; 
     } 
    } 
} 

No hay manera de permitir que la excepción se propague, ya que plantea una excepción comprobada (y que es ilegal durante la inicialización). Hay un par de maneras de lidiar con eso:

  • lanzar una excepción sin control: Esto provoca una java.lang.ExceptionInInitializerError para obtener plantearon cuando se intenta cargar la clase. Puede ser confuso y difícil de rastrear y depurar. No lo recomiendo

  • cambio en una variable no final, y crear una función para acceder a ella: Si no final de la variable, se puede comprobar si está configurado en el GET, y elevar la excepción comprobada, si no lo es. Esto permite (de hecho, requiere) su código para manejar la excepción en el punto donde se llama:


public class MyClass { 
    private static Setter setter; 

    protected static synchronized Setter getSetter() raises FileNotFoundException { 
     if setter == null { 
      setter = new Setter(); 
     } 

     return setter; 
    } 
} 
+0

¿Qué pasa si se trata de un error fatal y debería propagarse? – sixtyfootersdude

+0

@sixtyfootersdude: envuélvalo en una exclamación sin marcar. –

Cuestiones relacionadas