Force Initialization of an enumerated type in Java

后端 未结 4 1212
星月不相逢
星月不相逢 2021-02-20 01:46

I am attempting to find a way to force Java to load/initialize an enumerated type (which is nested within a class that contains a static Map).

This is important to me be

相关标签:
4条回答
  • 2021-02-20 01:49

    You can just reference something in the enum class. For example:

    public class EnumTest {
      static final Map<String, MyEnum> map = new HashMap<String, MyEnum>();
    
      enum MyEnum {
        FOO, BAR, BAZ;
    
        MyEnum() {
          map.put(name(), this);
        }
      }
      static {
        // ensure MyEnum is initialized
        MyEnum.values();
      }
    
      public static void main(String[] argsa) {
        System.out.println(map.size());
      }
    }
    
    0 讨论(0)
  • 2021-02-20 01:50

    Can't you just put initialization of the map in the static initializer of the Enum type?

    public enum SomeEnum
    {
        Member1, Member2, Member3 ...
    
        private static Map<K, SomeEnum> map = ...;
        static 
        {
            ...populate map...
        }
        ...
    

    EDIT: It appears that the issue was that the Enum member definitions need to come first. I guess I just glossed over this. I fixed the example.

    0 讨论(0)
  • 2021-02-20 01:54

    Seems like this is exactly why it is often recommended to use accessor methods instead of directly referencing members. Your problem is that the code allows access to the map before it is initialized. Block arbitrary access to the map, and hide it behind an accessor method that makes sure it is initialized.

    import java.util.Map;
    import java.util.HashMap;
    
    public enum EnumTest {
      FOO, BAR, BAZ;
    
      private static Map<String,EnumTest> map = null;
    
      public synchronized static Map getMap() {
        if (map == null) {
          map = new HashMap<String,EnumTest>();
          for ( EnumTest e : EnumTest.values() ) {
            map.put( e.name(), e );
          }
        }
    
        return map;
      }
    
      public static void main(String[] args) {
        System.out.println( EnumTest.getMap().size() );
      }
    }
    
    0 讨论(0)
  • 2021-02-20 02:03

    A class is loaded when you reference a class. This works the same for all classes.

    The problem you have is more likely to be that an Enum value is initialised before any static block. i.e. you cannot refer to something initialise in a static block in a constructor. (Generally initialising static content in a constructor is a BAD idea) You need to initialise the Map in the static block, not the constructor.

    Try

    import java.util.Map; 
    import java.util.HashMap; 
    
    public enum EnumTest { 
      FOO, BAR, BAZ; 
    
      private static final Map<String,EnumTest> map = new LinkedHashMap<String,EnumTest>(); 
      static { 
          for(EnumTest e : EnumTest.values())
            map.put(e.name(), e); 
      } 
    
      public static void main(String... args) { 
        System.out.println(EnumTest.map); 
      } 
    }
    
    0 讨论(0)
提交回复
热议问题