开发者

How to force instantiation of static fields

I was quite surprised of the output of the following code:

Country class

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);
   开发者_JAVA技巧 }

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

}

Main method

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

Output

null

Is there any clean way of forcing the class that extend Country to be loaded so the countries map contains all the Country instances?


Yes, use static initializer block:

public class Country {

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

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

    }

...


Your class EuropeCountry was not loaded at the time you called Country.getCountry("Spain"). The correct solution would be

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

This is just an example... There are other ways to achieve the same (see also Peter's answer)


You need to load the EuropeCountry class. Any reference to it before calling Country will enough.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜