在超级构造函数中传递需要`this`的对象?

时间:2019-05-23 18:06:12

标签: java

我正在设计一个类层次结构,我以标题的形式遇到了问题,这里是它的一个较小的抽象:

public abstract class A {
    private C c;

    public A(C c) {
        this.c = c;
    }

    // ...
}

public class B extends A {
    private int a;
    private int b;
    // ...

    public B(int a, int b, ... /* and more but no object of C */) {

        super(new C(this)); // <-- this is the point, got error:
                            //   can't access `this` .

        this.a = a;
        this.b = b;
        // ...
    }
}

public class C {
    private A a;

    public C(A a) {
        this.a = a;
    }
}

简而言之:A需要保留对C的引用,反之亦然,但是两者都应在其构造函数中完成,并且在构造完这两个字段之后,A aC c不应更改,因此我将它们设置为private。那么在这种情况下,最佳实践是什么?

以下实际上不是一个很好的例子,但关键是我有一种情况需要做以上尝试做的事情。

(更多情况:现在,我将private C c;中的class A更改为

private List<C> someCs;

即:AC的容器,因此在某些情况下需要对这些C进行排序。对于每个C的某个客户端,客户端需要知道其父级是什么,即它属于哪个A。在这种情况下,我需要两个方向的参考。)

1 个答案:

答案 0 :(得分:0)

this在构造函数完成后才是其他对象的有效引用。因此,无法在构造函数中初始化这种循环依赖关系(父级引用子级,子级引用父级)。父子引用也不能是final,因为final必须在构造函数中初始化。

您可以编写一个工厂来初始化所有父母和孩子。然后在所有初始化之后,您可以交叉引用它们。但这需要child.parentparent.child才能被工厂访问。他们是公开的还是有公开的二传手。您还可以执行其他一些特技操作,以允许工厂在父母和子女中设置私有变量,但我不建议这样做。

这是针对您情况的一项建议:创建一个跟踪父母和孩子之间映射的对象。映射具有方法getParent(this),在需要父方法时从子方法调用。以及在需要其子级时从父级调用的方法getChildren(this)getChildrenSorted(this)

该映射可以初始化一次,然后使用private和final锁定,这不会阻止运行时的进一步更改。然后,每个父母和孩子都可以获得对该对象的私有且最终的引用。

有关更多信息: