本文介绍了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] 最近发现。根据该网站,它通过动态检测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.

你可以尝试使用类似的东西:

You can try with something like:

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

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

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

08-24 07:07