保持对传递给超级构造函数的新对象的引用

时间:2012-10-04 22:49:42

标签: java constructor field super

是否有一种很好的方法来维护对在构造函数中创建的对象的引用,该对象需要传递给某个扩展类的超级构造函数(除了可以从超类访问它或将其作为一个传递给构造函数)参数)?

让我用一个例子来澄清。拿这个课程(我无法修改,哪些不能让我访问foo):

class TestA {
    TestA(Object foo) {}
}

现在,我想扩展这个类,如下所示:

class TestB extends TestA {
    Object myCopyOfFoo;

    TestB() {
        super(new Object());
    }
}

有没有一种方法可以将创建的new Object()存储在myCopyOfFoo

这三个想法中没有一个有效:

TestB() {
    myCopyOfFoo = new Object();
    super(myCopyOfFoo);
}

(错误:构造函数调用必须是构造函数中的第一个语句)

TestB() {
    super(myCopyOfFoo = new Object());
}

(错误:显式调用构造函数时无法引用实例字段myCopyOfFoo)

TestB() {
    super(makeFoo());
}

Object makeFoo() {
    myCopyOfFoo = new Object();
    return myCopyOfFoo;
}

(错误:显式调用构造函数时无法引用实例方法)

我想我可以做到以下几点,但它既不是线程安全也不优雅:

static Object tempFoo;

TestB() {
    super(tempFoo = new Object());
    myCopyOfFoo = tempFoo;
}

有没有人对我有更好的想法?为什么我的前两个想法不合法?

3 个答案:

答案 0 :(得分:17)

怎么样:

class TestB extends TestA {
    Object myCopyOfFoo;

    // I assume you actually wanted this to take a parameter called foo?
    // I've left it as per the question...
    TestB() {
        this(new Object());
    }

    private TestB(Object copy) {
        super(copy);
        myCopyOfFoo = copy;
    }
}

由于第二个构造函数是私有的,它只能在同一个类(或一个封闭的类)中调用,所以你只需要确保调用第二个构造函数的任何东西都做了一个适当的副本,就像第一个构造函数那样。

编辑:如果您的真实情况是您正在获取现有参数的副本,那么这将有效......

class ClassB extends ClassA {
    private final Foo copyOfInput;

    ClassB(Foo input) {
        super(input = input.clone());
        copyOfInput = input;
    }
}

虽然很难看:(

答案 1 :(得分:1)

另一种选择:

public class TestB extends TestA {

    Object myCopyOfFoo;

    private TestB(Object foo) {
        super(foo);
        myCopyOfFoo = foo;
    }

    public static TestB createInstance() {
        Object foo = new Object();
        return new TestB(foo);
    }

}

答案 2 :(得分:0)

以下内容如何:

class TestB extends TestA {
    Object myCopyOfFoo = new Object();

    TestB() {
        super(myCopyOfFoo);
    }
}

只有在创建新对象TestB时才会初始化对象,所以实际上这可以做你想做的事情吗?