Can an enumeration have constructors for each of its constants

Look at the link. In his book Effective Java, Joshua Bloch Says

Note that the operation constants are placed in the stringToEnum map from the static block, which is launched after the constants are created.

Trying to make each constant put itself on a map from its own constructor will cause a compilation error

. This is good because it will throw a NullPointerException if it was legal.

Enum constructor arguments are allowed to access static enumeration fields, with the exception of compile-time constant fields .

This restriction is necessary because these static fields have not yet been initialized when the constructors started.

I have two questions

  • Can Enums have separate constructors for each constant?
  • Why are compile-time constant fields available in constructors, but not in static fields?

thanks

+7
java enums constructor effective-java
source share
3 answers

Regarding the first question: you cannot have separate constructors, but you can work around this as follows:

public enum EnumTest { ONE() { void init() { val = 2; } }, TWO() { void init() { val = 1; } }; protected int val; abstract void init(); EnumTest() { init(); } } 

Thus, you have technically separate initialization methods for different constants.

Another way is to use initializer sections:

 public enum EnumTest { ONE() {{ val = 2; }}, TWO() {{ val = 1; }}; protected int val; } 

As for your second question: constant fields are not available at the time of enumeration creation, because constant variables are available for static fields. For example, this code compiles correctly:

 public enum EnumTest { ONE, TWO; public static final String ONE_STRING = ONE.toString(); } 

If access to ONE_STRING from the constructor was allowed, you would either have an infinite initialization cycle, or would have access to an uninitialized enumeration constant.

+4
source share
  • No, and I don’t think it means that it means a Flea, although it was not formulated in the best way. enum can have constructors, like enum Operation in a book. What Bloch means with its own constructor is: when the Operation constructor works for this particular constant.

  • The above has already been answered:

    This restriction is necessary because these static fields were not yet initialized when the constructors started.

+4
source share

Regular rules for designers apply. You can have as many constructors as you want if they have different signatures. Different enum values ​​can be built using different constructors:

 enum StringAndNumber { Zero("zero"), Five(5), Pi("Pi", 3.14159); private final String str; private final Number num; private StringAndNumber(String str) { this.str = str; this.num = null; } private StringAndNumber(Number num) { this.num = num; this.str = null; } private StringAndNumber(String str, Number num) { this.str = str; this.num = num; } } 
+2
source share

All Articles