10

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

让我用一个例子来澄清一下。参加这个课程(我无法修改,也无法访问 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;
}

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

4

3 回答 3

19

怎么样:

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;
    }
}

虽然很丑:(

于 2012-10-04T22:51:25.960 回答
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);
    }

}
于 2016-01-11T09:39:31.147 回答
0

以下情况如何:

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

    TestB() {
        super(myCopyOfFoo);
    }
}

该对象只会在创建新对象TestB时被初始化,所以本质上这会做你想要的吗?

于 2012-10-04T22:54:39.173 回答