2011-05-11 80 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類。在撥打國家之前提及它就足夠了。