I see three issues with static initialization:
- Global Variables.
- Complex initialization order.
- Unexpected error conditions.
Most initialization code is going to store some values (config parameters,
DB connections, etc) into global variables. There are many other questions about global variable usage, I would say the summary is global variable are generally bad, but there are exceptions and initialization is often sighted as one of the exceptions.
Depending upon your language it is not always obvious the order initialization code runs:
- Sometimes all the code runs before main.
- Sometimes initialization code can run when something is loaded (after the app proper has started).
- And when multiple items are loaded/referenced the order of initialization between them can be unclear.
In Java if a static initializer throws an exception, that exception will propagate back up the call stack - however a second reference to the class will result in a ClassNotFoundException - this is simply an example of a weird situation that can occur when initialization goes wrong - unfortunately it needs to be handled in more places when the initialization order/sequence is non-obvious.
So there are certainly issues associated with distributed/static initialization - however if you make initialization explicit (every class library etc has an initialization function that must be manually called) you run the risks of not initializing something or initializing items out of order.
I suspect (no evidence for this) that a lot of static initialization creeps in simply to allow sane defaults to be added so that other developers can get started quickly with libraries/frameworks.
In summary, I would suggest avoiding static initialization in your own code, but I wouldn't freak out about it too much in standard frameworks/libraries.