Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static Circular Dependency in Java

for the following code:

class A
{
    public static int X;
    static { X = B.Y + 1;}
}
public class B
{
    public static int Y = A.X + 1;
    static {}
    public static void main(String[] args) {
        System.out.println("X = "+A.X+", Y = "+B.Y);
    }
}

the output is: X = 1, Y = 2

Why? and How???

-Ivar

P.S: Code snippet taken from JavaCamp.org

like image 407
topgun_ivard Avatar asked Jun 20 '11 19:06

topgun_ivard


People also ask

What is circular dependency in Java?

A circular or cyclic dependency is a situation where two or more independent modules or components rely on each other to function properly. This is referred to as mutual recursion. Circular dependency generally occurs in a modular framework while defining a dependency between modules or components.

How do you avoid circular dependencies?

Avoiding circular dependencies by refactoring The NestJS documentation advises that circular dependencies be avoided where possible. Circular dependencies create tight couplings between the classes or modules involved, which means both classes or modules have to be recompiled every time either of them is changed.

How do I get rid of cyclic dependency?

The Mediator Pattern can also help to lift circular dependencies by encapsulating the bidirectional interaction of two or more objects. The downside of your current code is (besides the circular dependency), that whenever class A changes and also data persistence changes, you have to touch and modify class B.


2 Answers

Here is what happens in chronological order:

  1. Class B contains the main-method so it is loaded by the class loader.

  2. Initialization of B references A, so class A is loaded.

  3. A has a static variable X initialized to B.Y + 1.

    The initialization of B.Y hasn't been executed yet, so B.Y evaluates to 0, and thus 1 is assigned to A.X

  4. Now A has finished loading, and the initialization of B.Y can take place.

    The value of A.X + 1 (1 + 1) is assigned to B.Y.

  5. The values of A.X and B.Y are printed as 1 and 2 respectively.

Further reading:

Java Language Specification, §12.4.1 When Initialization Occurs

like image 92
aioobe Avatar answered Oct 26 '22 12:10

aioobe


This is only my guess:

  1. Class B is loaded because it contains main which you have requested to be executed.
  2. Class loader discovers that B requires A to operate (it uses A by accessing its static field)
  3. Class B is loaded.
  4. Class A requires class B which happens to be already loaded, but not yet initialized
  5. A carelessly loads B.Y (initialized to 0 by that time by default), since the class looks like loaded (language design flaw?)
  6. A.X = 0 + 1
  7. A is now loaded, class loader can continue to load and initialize B
  8. B.Y = 1 + 1.
like image 40
Tomasz Nurkiewicz Avatar answered Oct 26 '22 11:10

Tomasz Nurkiewicz