4

我基本上想要的是这个:

public class Test 
{    
   private static final Integer a;

   public Test(Integer a) 
   {
      this.a = a;
   }

}

这显然不起作用,因为第二个创建的实例会尝试覆盖最终变量。那么有没有办法通过构造函数为所有实例赋予相同的不可变值?

4

2 回答 2

12

静态最终值应该在静态上下文中初始化,而不是通过实例。

一种选择是在声明中设置值:

private static final Integer a=FileConfig.getInstance().getA();

每个类都可以有一个静态 {} 块,其中调用代码来初始化类的静态部分。

static {
    a = FileConfig.getInstance().getA();
}

最后,您可以从静态方法中设置值

private static int getA() {
    return FileConfig.getInstance().getA();
}

private static final Integer a=getA();

在闭包中,静态实例初始化不属于实例构造函数。

如果配置值有时会发生变化,则根本没有理由将值 a 存储在静态最终变量中。如果要在构造函数中使用常量 a 创建每个实例,首先静态字段的目的是什么?不知何故,当您第一次调用构造函数时,您正在从某个地方传入一个值。如果该值应该是静态的和最终的,您可以从静态初始化器中获取它。如果配置不是单例,但每个实例总是产生相同的 a 值,你可以很容易地做到a = new FileConfig().getA();.

除此之外,您可以将值设为非最终值,并请放心,由于您始终输入相同的值a,静态变量不会改变。

不过,您可以a在构造函数中设置类的最终实例变量。

于 2012-10-23T23:16:15.953 回答
2

那么有没有办法通过构造函数为所有实例赋予相同的不可变值?

我假设您希望a在第一次创建类型对象时分配一个值,Test而不是在创建任何后续实例时分配一个值。在这种情况下,您不能声明它finala最初将为 null,构造函数必须检查它是否为 null 并在这种情况下为其分配一个值。

但我敦促您查看设计,特别是为什么调用者必须提供该值。在创建第二个Test对象后 Test.a 在以下情况下没有改变,这不是违反直觉吗?

// assume this is the first `Test` object created:
Test t = new Test(5); // Test.a is 5
Test t = new Test(6); // Test.a is *still* 5
于 2012-10-23T23:17:21.197 回答