如何强制实例化静态字段

时间:2011-05-11 11:32:41

标签: java static

我对以下代码的输出感到非常惊讶:

国家/地区类

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

输出

  

是否有任何干净的方法强制扩展国家/地区的类以便加载,以便国家/地区地图包含所有国家/地区实例?

3 个答案:

答案 0 :(得分:7)

是的,请使用static initializer block

public class Country {

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

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

    }

...

答案 1 :(得分: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) {}
}

这只是一个例子......还有其他方法可以达到同样的效果(参见Peter的回答)

答案 2 :(得分:0)

您需要加载EuropeCountry课程。在调用Country之前对它的任何引用都足够了。