2013-08-26 181 views
3

我需要将类型B的对象链接到类型A(循环依赖项)的任何实例。我也可以声明另一个方法,它必须在A的构造函数之后调用,并将新的B链接到A实例。我想实现的是不必手动调用这种方法。这是示例代码:使用self(this)在构造函数中调用构造方法 - 参数

public Class A{ 
    B b; 
    public A(){ 
     b = new B(this); // this does not work, 
         // as this references an object that has not been created yet 
    } 
} 

public Class B{ 
    A a; 
    public B(A a){ 
     this.a = a; //or something else 
    } 
} 

我评论了有问题的行。我也明白为什么它不能工作。我需要知道的是,如果有一个众所周知的设计模式来避免这个问题?或者我应该重新设计我的班级模型,把B中的任何东西放到A中?有什么建议么?

+0

你必须学习依赖注入原则,它是Spring框架的核心,并且在那里解决这些类型的问题 – Algorithmist

+0

你在做什么?鉴于项目细节可能会影响不同的答案。 –

+0

您可能只需要使用set方法。我不知道你将如何在构造函数中做到这一点。 – taronish4

回答

4

确实工作。它的问题在于它在对象被完全初始化之前暴露了一个对象(因此如果B构造函数调用参数的方法,例如,这可能是一件坏事),但它的确可以工作工作。参考文献B.a将参考已经/正在构建的A实例。

我会建议尽可能避免循环引用,但在替代方案更糟的情况下,您提供的代码将起作用。

+0

在这种情况下我们不能考虑使用依赖注入吗? – Algorithmist

+1

@Algorithmist:那么如果这两个字段实际上是'final',那么依赖注入并没有什么实际的帮助 - 在引用对象的对象中得到两个最终字段的唯一方法就是使用类似的东西。我们在这里没有足够的背景来评论替代方案。 –

+0

@JonSkeet A类是一个图类。有数据结构和方法来处理图形(添加和删除边缘,等等)。 B类是一个度序列类,用一些方法来计算度序列,调整它们等等。在我的模型中,每个图形对象都应该有一个度数序列对象,图形本身应该是最终的。我不知道依赖对象是如何工作的,因为度数序列可以在构建图时首先计算,而度数序列应该在图创建之后构建。 – yogii

1

不推荐使用此方法,因为对象未完全初始化,可能会创建运行时异常。我们可以采取简单的方案为:

public class A { 
    B b; 
    String s; 
    public A(){ 
     b = new B(this); // this does not work, as this references an object that has not been created yet 
     s = "print me"; 
    } 
} 


public class B { 
    A a; 
    public B(A a){ 
     this.a = a; //or something else 
     System.out.println(this.a.s); // will same as a.s; 
    } 
} 

它将输出null因为部分初始化引用复制到构造函数。此代码编译是因为编译器在代码中找不到任何缺失,因为所有适当的引用和变量都在那里。

相关问题