Java构造函数中的循环依赖 [英] Circular dependency in Java constructors

查看:99
本文介绍了Java构造函数中的循环依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下课程.

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 .

As can be clearly seen, there is a circular dependency between the classes. if I try to run class A, I eventually get a StackOverflowError.

如果创建了一个依赖图,其中节点是类,那么可以轻松地识别这种依赖(至少对于节点很少的图).那么,为什么JVM至少在运行时无法识别这一点?JVM至少可以在开始执行之前发出警告,而不是引发 StackOverflowError .

If a dependency graph is created, where nodes are classes, then this dependency can be easily identified (at least for graphs with few nodes). Then why does the JVM not identify this, at least at runtime? Instead of a throwing StackOverflowError, JVM can at least give a warning before starting execution.

[更新] 某些语言不能具有循环依赖关系,因为这样就无法生成源代码.例如,查看此问题和可接受的答案.如果循环依赖性是C#的设计味道,那么为什么Java却没有呢?仅因为Java可以(编译具有循环依赖项的代码)?

[Update] Some languages cannot have circular dependencies, because then the source code will not build. For example, see this question and the accepted answer. If circular dependency is a design smell for C# then why is it not for Java? Only because Java can(compile code with circular dependencies)?

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

[update2] Recently found jCarder. According to the website, it finds potential deadlocks by dynamically instrumenting Java byte codes and looking for cycles in the object graph. Can anyone explain how does the tool find the cycles?

推荐答案

您的类A的构造函数调用类B的构造函数.类B的构造函数调用类A的构造函数.您有一个无限递归调用,即为什么最终会出现 StackOverflowError .

The constructor of your class A calls the constructor of class B. The constructor of class B calls the constructor of class A. You have an infinite recursion call, that's why you end up having a StackOverflowError.

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

Java supports having circular dependencies between classes, the problem here is only related to constructors calling each others.

您可以尝试以下操作:

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

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

这篇关于Java构造函数中的循环依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆