7

在java中构造对象时可以this作为参数传递给方法吗?

想到这样做让我感到不安,但我不确定这是否肯定是错误的。举一个假设的例子:

public final class A {
    private final B b;
    private final List<String> words;

    public A(B b) {
        this.b = b;
        words = new ArrayList<String>();
        for(int i = 0; i < 10; i++) {
            words.add(b.getNextStringFromUser(this));
        }
    }

    public List<String> getWords() {
        return words;
    }
}

public class B {
    // returns a String chosen by the user based on the current state of A
    public String getNextStringFromUser(A a) {
        List<String> wordsSoFar = a.getWords();
        // ... omitted
    }
}

我能想到的情况可能是正确的做法是,您想要构造一个从其余代码的角度来看可以是不可变的对象,但是构造函数可能会采取不同的过程,具体取决于到目前为止指定的状态(如果谈论部分构造对象的状态是有意义的)。在上面的示例中,用户根据到目前为止选择的字符串选择一个字符串,当它们都被选中时,这个对象应该永远不会再改变。

这种事情可以/可取吗?谢谢。

4

5 回答 5

2

Java 语言对类的构造是明确的。请参阅此处的规范。如果您确定您正在调用的代码仅访问已初始化的状态,那么它可能是安全的。

于 2013-09-13T19:39:53.867 回答
2

在构造函数中泄漏“this”引用是危险的,尤其是在多线程环境中。您最终可能会得到其他线程不可见的未完全构造的对象。但是,如果从单线程中使用它可能会表现得很好,但是这种错误真的很难找到和修复。因此,如果您的 IDE 将其标记为警告,请不要感到惊讶。

于 2013-09-13T19:30:42.987 回答
2

在java中构造对象时作为方法的参数?

我会think twice的,因为你的object is not even constructed fully.

它可能有一些attributes which are still null or unitialized.,如果其他一些类访问那些将为空的属性,请准备好NULL POINTER EXCEPTIONS

希望这可以帮助。

于 2013-09-13T19:30:11.293 回答
1

在您提出的情况下,这是不可接受的。

出于安全原因,您应该尽量避免传递未初始化/部分初始化的对象。在您的情况下,您可以重新声明getNextStringFromUser(A a)为:

public String getNextStringFromUser(List<String> wordsSoFar) {
        // ... omitted
}

此外,您有两个需要相互引用的对象的场景并不常见。查看MVC 设计模式工厂设计模式可能很有用。

是一个类似的问题,除了只有一个对象引用了另一个对象。

于 2013-09-13T19:52:03.147 回答
0

您的代码中的问题不是传递this给另一个方法,问题是您在构造函数中执行它,这意味着即使在完成初始化之前,另一个对象也将访问您的类。

于 2013-09-13T19:30:57.767 回答