Java类互相引用

时间:2015-06-28 14:09:25

标签: java class

我有两个java类文件。他们每个人都有另一个使用的方法。

public class class1{
    class2 c2 = new class2(); 
    m1(){
        c2.ma(); 
        m2();
    }
    m2(){}
}

public class class2{
    class1 c1 = new class1();
    ma(){}
    mb(){
        c1.m2();
    }
}

class1 c1 = new class1();  

class2 c2 = new class2();  

互相引用导致无限循环,导致java.lang.StackOverflowError错误。

有没有办法让课程互相引用,或者我别无选择,只能将我的所有方法转移到一个班级?

3 个答案:

答案 0 :(得分:6)

如上所述,这是代码嗅觉的标志。

有一个setter来设置之后的方法并不令人满意,因为你有一个处于不确定状态的对象,直到调用setter。

尽管使用Spring等依赖框架可以帮助解决上述问题,但如果使用构造函数注入,那么也不能有循环依赖关系!但至少在注入豆子时,你确定它不是一半构造的。

如果您不想使用依赖项注入框架,请考虑一个工厂模式,其中两个对象都是由工厂方法创建的,该方法返回一个元组(或者在Java的情况下没有本机支持的容器对象)元组包含完全构造的对象。

答案 1 :(得分:1)

  

有没有办法让课程互相引用或者我有   别无选择,只能将我的所有方法转移到一个班级?

在我看来,循环引用是一种代码气味。有关说明,请参阅this答案。请特别注意关于cognitive load

的观点

解决方案是让一个类依赖另一个类并将调用委托给另一个类:

public class class1{
    class2 c2 = new class2(); 
    m1(){
        c2.ma(); 
        m2();
    }
    m2(){}
}

public class class2{
    ma(){}
}

这样,您并没有真正将所有方法转移到一个类,只是将class2组合成class1。其他依赖class1class2的类只需要依赖class1

答案 2 :(得分:0)

实际发生的是您在构造函数中创建Class1的实例,

  • 在构造函数中创建Class2的实例,
    • 在构造函数中创建Class1的实例,
      • 在构造函数中创建Class2的实例,
        • 等等。

您的构造函数会递归地创建实例,导致调用堆栈泛滥,导致StackOverflowError

我假设您希望Class1的实例保存对Class2实例的引用,反之亦然?

在这种情况下,你可以这样做:

public class Class1 {

    private Class2 c2;

    public Class1() {
        this.c2 = new Class2(this);
    }
}

public class Class2 {

    private Class1 c1;

    public Class2(Class1 class1) {
        this.c1 = class1;
    }
}
像这样的循环聚合通常是设计糟糕的标志;但是 的情况下它完全有效,或者至少反映现实。