In a bigger project I am experiencing a strange behavior (at least for my understanding) with static field initialization. As I understand it, all static fields should be initialized at program start, meaning that when starting to work with a non-static field, there should not be any non-initialized static fields (more precisely, all static assignments "field = ..." should have been performed).
The following code is NOT a MWE, because it DOES what I expect it to, but it is essentially exactly what I'm doing in the bigger context. I have not been able to create a smaller example which results in the same problem.
When running this code:
import java.util.HashSet;
public class FB {
private static final HashSet<String> collection = new HashSet<>();
public static final String foo = bar("item");
public static String bar(String newItem) {
collection.add(newItem);
System.out.println("Yes, I've been invoked, and I currently store this: " + collection);
return newItem;
}
public static void main(String[] args) {
}
}
the output is (as Java initializes first the static field 'collection' and then foo by invoking bar(.)):
Yes, I've been invoked, and I currently store this: [item]
So far, so good. In the real project, I am doing exactly this (although foo and bar(.) are in different classes), but bar(.) is NOT invoked before I actually use the value of foo. (At least this happens in one case out of five - which are all created in the same way as shown above. The other four work fine.) Are there any circumstances which would cause Java behaving like this?
I already looked at these discussions, but they do not seem to capture my problem:
When are static variables are initialized?
Why static fields are not initialized in time?
Java Static Field Initialization
I realize that, when swapping the positions of foo and collection, the method invokation cannot work because collection would not be initialized (or rather, initialized to null?) when foo gets initialized. (To be honest, I am not sure in which order static fields are initialized when located in different classes, so this might be a source of problems.) But this would result in a
Exception in thread "main" java.lang.ExceptionInInitializerError
and not in just not invoking bar(.).
If required, I can provide more details about the real project, but so far I don't know what else might be of interest. (Sorry for the fuzzy description, but this is all I have so far.)