foamroll
foamroll

Reputation: 813

What guarantees that this call to a static method from another class's static block works as expected?

Class A contains:

Class B contains:

Will B's static block always successfully populate its map? I'm assuming that the JVM is able to handle this. Could there be any issue with regards to the order in which the static blocks are executed when the classes are loaded, which in turn could not guarantee B populating the map correctly? I'd like to be certain, and perhaps understand the mechanism behind this.

Upvotes: 3

Views: 119

Answers (1)

ZhongYu
ZhongYu

Reputation: 19682

If two classes have circular dependency during static initialization, things get tricky. Java does have a strictly defined initialization procedure, and back off when recursion is detected. However it will depend on which class initialization is triggered first at runtime. This means a partial initialized class could be visible (in your case, seeing a null getStr).

Circular dependency is not only confusing, it may even cause deadlock, if two classes are initialized from two different threads. Therefore it should be avoided at all cost. A circular dependency between two parties can always be resolved by introducing a 3rd party.

Without circular dependency, a class is always seen fully initialized; in your case, when B calls A.getStr(), it must be the case that A is fully initialized, and getStr() returns the desired value.


As an exmaple of circular dependency, suppose class A extends B.

If B is initialized first (e.g. by someone calling B.something), there is no problem; during B's initialization, it encounters A.getStr, this will trigger A's initialization; when that is done, A.getStr is then executed, and sees a properly initialized field.

However, if A is initialized first, there will be trouble; it will trigger superclass B's initialization; when B invoked A.getStr, VM sees that A is already in the process of initialization, so it backs off and won't try to finished A's initialization; A.getStr will simply see null.

To break this circle, we can move stuff in A that B depends on to A'. Both A and B will depend on A'.

Upvotes: 2

Related Questions