Java类互相引用
我有两个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错误。
是否有某种方法让这些类相互引用或者我别无选择只能将我的所有方法转移到一个类中?
如上所述,这是代码气味的标志。
之后有一个setter来设置方法并不令人满意,因为你有一个处于不确定状态的对象,直到调用setter。
虽然使用Spring之类的依赖框架可以帮助解决上述问题,但是如果使用构造函数注入,那么你也不能拥有循环依赖! 但至少在注入豆子时,你确定它不是一半构造的。
如果您不想使用依赖项注入框架,请考虑一个工厂模式,其中两个对象都是由工厂方法创建的,该方法返回一个元组(或者在Java的情况下对于元组没有本机支持的容器对象)完全构造的物体。
是否有某种方法让这些类相互引用或者我别无选择只能将我的所有方法转移到一个类中?
在我看来,循环引用是代码气味。 请参阅此答案以获得解释。 特别注意关于cognitive load
的观点。
解决方案是让一个类依赖于另一个类并将调用委托给另一个类:
public class class1{ class2 c2 = new class2(); m1(){ c2.ma(); m2(); } m2(){} } public class class2{ ma(){} }
这样,你并没有真正将所有方法转移到一个类,而只是将class2
组成class1
。 其他依赖于class1
和class2
只需要依赖class1
。
实际发生的是你在构造函数中创建了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; } }
像这样的循环聚合通常是设计糟糕的标志; 但有些情况下它完全有效,或者至少反映现实。