ath*_*ena 33 java circular-dependency
我有以下课程.
public class B
{
public A a;
public B()
{
a= new A();
System.out.println("Creating B");
}
}
Run Code Online (Sandbox Code Playgroud)
和
public class A
{
public B b;
public A()
{
b = new B();
System.out.println("Creating A");
}
public static void main(String[] args)
{
A a = new A();
}
}
Run Code Online (Sandbox Code Playgroud)
可以清楚地看到,类之间存在循环依赖关系.如果我试着跑A级,我最终会得到一个StackOverflowError.
如果创建了依赖关系图,其中节点是类,则可以轻松识别此依赖关系(至少对于具有少量节点的图).那为什么JVM不能识别这个,至少在运行时?StackOverflowErrorJVM可以在开始执行之前至少发出警告,而不是抛出.
[更新]某些语言不能具有循环依赖关系,因为这样就不会构建源代码.例如,请参阅此问题和接受的答案.如果循环依赖是C#的设计气味那么为什么它不适用于Java呢?只是因为Java可以(编译循环依赖的代码)?
[update2]最近发现了jCarder.根据该网站,它通过动态检测Java字节代码并在对象图中查找周期来发现潜在的死锁.任何人都可以解释该工具如何找到周期?
Viv*_*sse 32
类A的构造函数调用类B的构造函数.类B的构造函数调用类A的构造函数.您有一个无限递归调用,这就是为什么你最终得到一个StackOverflowError.
Java支持在类之间具有循环依赖关系,此处的问题仅与构造函数相互调用有关.
您可以尝试使用以下内容:
A a = new A();
B b = new B();
a.setB(b);
b.setA(a);
Run Code Online (Sandbox Code Playgroud)
如果您真的有这样的用例,您可以按需(懒惰地)创建对象并使用 getter:
public class B
{
private A a;
public B()
{
System.out.println("Creating B");
}
public A getA()
{
if (a == null)
a = new A();
return a;
}
}
Run Code Online (Sandbox Code Playgroud)
(对于班级也类似A)。因此,如果您执行以下操作,则只会创建必要的对象:
a.getB().getA().getB().getA()
Run Code Online (Sandbox Code Playgroud)