Friday, May 24, 2019

java - Execution order of of static blocks in an Enum type w.r.t to constructor



This is from Effective Java :



// Implementing a fromString method on an enum type
private static final Map stringToEnum
= new HashMap();


static { // Initialize map from constant name to enum constant
for (Operation op : values())
stringToEnum.put(op.toString(), op);
}

// Returns Operation for string, or null if string is invalid
public static Operation fromString(String symbol) {
return stringToEnum.get(symbol);
}




Note that the Operation constants are put into the stringToEnum map
from a static block that runs after the constants have been created.
Trying to make each constant put itself into the map from its own
constructor would cause a compilation error. This is a good thing,
because it would cause a NullPointerException if it were legal. Enum
constructors aren’t permitted to access the enum’s static fields,
except for compile-time constant fields. This restriction is necessary

because these static fields have not yet been initialized when the
constructors run.




My question is regarding the line :




"Note that the Operation constants are put into the stringToEnum map
from a static block that runs after the constants have been created" .





I thought the static block gets executed before the constructor runs. The are actually executed during class load time.



What am I missing here ?


Answer



I understand your question as: why is there a guarantee that the enum constants will be initialised before the static block is run. The answer is given in the JLS, and a specific example is given in #8.9.2.1, with the following explanation:




static initialization occurs top to bottom.





and the enums constants are implicitly final static and are declared before the static initializer block.



EDIT



The behaviour is not different from a normal class. The code below prints:



In constructor: PLUS
PLUS == null MINUS == null


In constructor: MINUS
PLUS != null MINUS == null

In static initialiser
PLUS != null MINUS != null

In constructor: after static
PLUS != null MINUS != null





public class Operation {

private final static Operation PLUS = new Operation("PLUS");
private final static Operation MINUS = new Operation("MINUS");

static {
System.out.println("In static initialiser");
System.out.print("PLUS = " + PLUS);

System.out.println("\tMINUS = " + MINUS);
}

public Operation(String s) {
System.out.println("In constructor: " + s);
System.out.print("PLUS = " + PLUS);
System.out.println("\tMINUS = " + MINUS);
}

public static void main(String[] args) {

Operation afterStatic = new Operation ("after static");
}
}

No comments:

Post a Comment

plot explanation - Why did Peaches' mom hang on the tree? - Movies & TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...