0

好吧,我有一个最终属性,但我不想在创建对象时初始化它,因为我做不到。所以我试图不在我的构造函数中初始化它,而是使用一个setter,我猜它会像一个只有一次可用的setter,但我有这个错误:

Test.java:27:错误:无法为最终变量 foo 赋值

    this.foo = new String(foo);

这是我用来测试的简短代码:

class Test {

    private final String foo;

    public static void main(String[] args) {
        Test test = new Test();
        test.setFoo("gygygy");
        System.out.println(test.getFoo());
    }

    public Test() {
        System.out.println("Constructor");
    }

    public String getFoo() {
        return foo;
    }

    public void setFoo(String foo) {
        this.foo = foo;
    }

}

所以我假设构造函数隐式地做了这样的事情 this.foo = new String(); 或 this.foo = null; 而且我认为我无法修改此行为,但是我怎样才能拥有与我想做的等效的行为?我认为是这样的:

private String foo;

/* ... */

public void setFoo(String foo) {
    if( !(this.foo.isInitialized()) )
        this.foo = foo;
}

但是 Object.isInitialized() 方法显然不存在,我找不到等效的 x)

所以这里是我的几句话的问题:我该怎么办?我想要一个在对象实例化时未初始化的最终属性

谢谢 !

4

3 回答 3

2

您可以添加一个布尔字段isInisialized,但最好的选择是在构造函数中传递值(如果需要,可能使用 Builder 模式)

于 2012-07-22T16:37:25.777 回答
1

所以这里是我的几句话的问题:我该怎么办?我想要一个在对象实例化时未初始化的最终属性。

你根本做不到。您所能做的就是拥有一个单独的字段,一旦您设置了“真实”字段,您也可以更新以记录 - 如果您尝试第二次设置它,则抛出异常。

或者,使您的类型不可变,但给它一个构造类的实例的方法,除了单个新值外,其数据与以前相同,例如

public Test withFoo(String newFoo) {
    // Call a private constructor here, passing in the other fields from
    // "this", and newFoo for the value of foo
}
于 2012-07-22T16:37:36.153 回答
0

规则说最终实例成员变量应该在声明它的地方或在构造函数中初始化。根据这条规则,您的代码不能按原样满足您的要求。您可以使用构建器模式来实现它。请参阅此链接Builder Pattern in Effective Java

于 2012-07-22T16:39:32.843 回答