Reputation: 813
Class A
contains:
Strings
Map
that is populated in the class's static
blockgetStr()
, that returns a String
built from the static
Strings
Class B
contains:
Map
Map
using A.getStr()
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
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