2011-05-11 22 views
7

的实例我很惊讶下面的代码的输出:如何强制静态字段

国家类

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); 
     } 
    } 

} 

主要方法

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

输出

是否有强迫延伸到加载国家,所以国家地图包含所有国家的实例类的任何干净的方式?

回答

7

是,使用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。请注意,静态块必须在国家代码或包含main的类中。 – Tarlog 2011-05-11 11:43:10

+0

唯一的问题是你失去了EuropeCountry.SPAIN和EuropeCountry.FRANCE的参考文献。 – eliocs 2011-05-11 14:24:52

3

你的类EuropeCountry你叫Country.getCountry("Spain")时未加载。正确的解决办法是

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) {} 
} 

这仅仅是一个例子......还有其他的方法来达到同样的(见彼得的答案)

+0

我喜欢这种强迫它的方式。 – eliocs 2011-05-11 15:47:10

0

您需要加载EuropeCountry类。在拨打国家之前提及它就足够了。