2012-07-22 219 views
0

嗯,我有一个最终属性,但我不想在创建对象时初始化它,因为我不能。于是,我就不能初始化它在我的构造函数,但使用二传手,我猜它会一直像一个只,一次性使用的二传手,但我有此错误:在对象实例化后初始化最终属性

Test.java:27: error: cannot assign a value to final variable 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)

因此,这里是我的几句话的问题:我能怎么做 ?我想要一个最终属性未在对象的实例化处初始化。

谢谢!

回答

2

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

+1

那么我会简单地使用布尔的解决方案,谢谢!我不知道建造者模式。我想我理解它是如何工作的,但我更喜欢第一种解决方案,它将以更快,更简单的方式用于单个属性:p – Thiht 2012-07-22 16:51:41

1

So here's my question in a few words : How can I do ? I want a final attribute that is not initialized at the instantiation of the object.

你根本无法做到这一点。所有你可以做的是有一个单独的领域,你更新记录,一旦你设置了“真实”字段 - 如果你尝试再次设置它,抛出一个异常。

或者,让你的类型不可变,但给它一个构造类的新实例的方法,其中除了单个新值之外,其余的数据与以前相同。

public Test withFoo(String newFoo) { 
    // Call a private constructor here, passing in the other fields from 
    // "this", and newFoo for the value of foo 
} 
+0

这种方法可以被多次调用,所以它就好像我的属性不是最终的,如果我没有误解 – Thiht 2012-07-22 16:57:32

+0

@Thiht:该方法将返回一个* new *对象...该字段将在构造函数中设置,因此它可能是最终的。 – 2012-07-22 17:32:18

+0

哦,好吧,我明白了。那么,感谢这个答案,它也应该在这种情况下工作。 – Thiht 2012-07-22 18:29:03

0

规则说最终的实例成员变量应该在声明它的地方或构造函数中进行初始化。通过这个规则,你的要求不能满足你的代码片段。您可以使用构建器模式来实现它。看到这个链接Builder Pattern in Effective Java