java - Java构造函数中的循环依赖

标签 java constructor circular-dependency

我有以下类(class)。

public class B 
{
    public A a;

    public B()
    {
        a= new A();
        System.out.println("Creating B");
    }
}

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();
    }
}

可以清楚地看到,类之间存在循环依赖关系。如果我尝试运行 A 类,我最终会得到一个 StackOverflowError

如果创建了一个依赖关系图,其中节点是类,那么这种依赖关系可以很容易地识别(至少对于具有少量节点的图)。那么为什么 JVM 至少在运行时没有识别出来呢? JVM 至少可以在开始执行之前发出警告,而不是抛出 StackOverflowError

[更新] 一些语言不能有循环依赖,因为那样的话源代码将无法构建。例如,see this question和接受的答案。如果循环依赖是 C# 的一种设计味道,那么为什么它不是 Java 的呢?只是因为Java可以(编译循环依赖的代码)?

[update2] 最近发现jCarder .根据该网站,它通过动态检测 Java 字节码并在对象图中查找循环来发现潜在的死锁。谁能解释一下该工具是如何找到循环的?

最佳答案

A 类的构造函数调用 B 类的构造函数。B 类的构造函数调用 A 类的构造函数。你有一个无限递归调用,这就是你最终得到 StackOverflowError 的原因.

Java支持类之间的循环依赖,这里的问题只与构造函数相互调用有关。

您可以尝试以下方法:

A a = new A();
B b = new B();

a.setB(b);
b.setA(a);

关于java - Java构造函数中的循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3646113/

相关文章:

java - 自定义绘画代码无法正确更新,我尝试尊重剪辑区域。运行一下看看

java - array.length 的运行时间是多少?

c++ - 复制构造函数和赋值运算符

java - 将 RealmObject 扩展为单例的类

angular - 复杂的 TypeScript 循环依赖问题

java - Tomcat 7 上的 URL 丢失应用程序名称

java - 我的 JAVA_OPTS 设置没问题吗?

具有双重分派(dispatch)的 C++ 多态循环依赖

c++ - 构造函数未初始化对象成员数据

C++:概念循环包含问题