How to force static fields

I was very surprised by 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); } @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")); 

Exit

zero

Is there any clean way to force a class that extends the country to load, so does the country map contain all instances of the country?

+7
source share
3 answers

Yes, use a static initialization block :

 public class Country { private static Map<String, Country> countries = new HashMap<String, Country>(); static { countries.put("Spain", new EuroCountry("Spain")); } ... 
+7
source

Your EuropeCountry class EuropeCountry not loaded while calling Country.getCountry("Spain") . The right decision 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 do the same (see also Peter’s answer)

+3
source

You need to load the EuropeCountry class. Any links to it before calling the country will be enough.

0
source

All Articles