Say you have this code snippet
private final Set set = new HashSet() {{ add(1); }};
SomeConstructor() {
printSet();
}
long printSet() {
new Thread(() -> {System.out.println(set)}).start();
}
for example if the compiler decided to make this look like
private final Set set;
SomeConstructor() {
printSet();
set = new HashSet() {{ add(1); }};
}
this would be a problem because calculateWaitTime() makes a new Thread that might see the set as null or not having a 1 in it.
So the question again, is this reordering possible? Or do all final fields initialized outside of the constructor get initialized before the constructor or at least moved to the top of the constructor always by the compiler
It's not possible for final
fields.
Just look at The Java ® Language Specification Java SE 8 Edition > 17.5.2 Reading final Fields During Construction:
17.5.2 Reading final Fields During Construction
A read of a final field of an object within the thread that constructs that object is ordered with respect to the initialization of that field within the constructor by the usual happens-before rules. If the read occurs after the field is set in the constructor, it sees the value the final field is assigned, otherwise it sees the default value.
But as you also can see it's not guarantied for subsequent final
field modifications using reflection. See 17.5.3 for more details.