2011-05-11 9 views
7

me quedé bastante sorprendido de la salida del siguiente código:cómo forzar la creación de instancias de los campos estáticos

clase País

public class Country { 

    private static Map<String, Country> countries = new HashMap<String, Country>(); 

    private final String name; 

    @SuppressWarnings("LeakingThisInConstructor") 
    protected Country(String name) { 
     this.name = name; 
     register(this); 
    } 

    /** Get country by name */ 
    public static Country getCountry(String name) { 
     return countries.get(name); 
    } 

    /** Register country into map */ 
    public static void register(Country country) { 
     countries.put(country.name, country); 
    } 

    @Override 
    public String toString() { 
     return name; 
    } 

    /** Countries in Europe */ 
    public static class EuropeCountry extends Country { 

     public static final EuropeCountry SPAIN = new EuropeCountry("Spain"); 
     public static final EuropeCountry FRANCE = new EuropeCountry("France"); 

     protected EuropeCountry(String name) { 
      super(name); 
     } 
    } 

} 

método Main

System.out.println(Country.getCountry("Spain")); 

salida

nula

¿Hay alguna forma limpia de obligar a la clase que se extienden País que se cargue por lo que el mapa de los países contiene todas las instancias del país?

Respuesta

7

Sí, utilice static initializer block:

public class Country { 

    private static Map<String, Country> countries = new HashMap<String, Country>(); 

    static { 
     countries.put("Spain", new EuroCountry("Spain")); 

    } 

... 
+0

+1. Solo preste atención a que el bloque estático debe estar en el código de país o en la clase que contiene main. – Tarlog

+0

único problema es que pierde las referencias de EuropeCountry.SPAIN y EuropeCountry.FRANCE. – eliocs

3

Su clase EuropeCountry no estaba cargada en el momento en que llamó Country.getCountry("Spain"). La solución correcta sería

private static Map<String, Country> countries = new HashMap<String, Country>(); 

static { 
    // Do something to load the subclass 
    try { 
     Class.forName(EuropeCountry.class.getName()); 
    } catch (Exception ignore) {} 
} 

Esto es sólo un ejemplo ... Hay otras maneras de lograr el mismo (véase también la respuesta de Pedro)

+0

Me gusta esa forma de forzarlo. – eliocs

0

Es necesario cargar la clase EuropeCountry. Cualquier referencia a esto antes de llamar al país será suficiente.

Cuestiones relacionadas