我有两个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错误。
有没有办法让课程互相引用,或者我别无选择,只能将我的所有方法转移到一个班级?
答案 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
。其他依赖class1
和class2
的类只需要依赖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;
}
}
像这样的循环聚合通常是设计糟糕的标志;但是 的情况下它完全有效,或者至少反映现实。