在构造函数中设置静态最终变量

时间:2012-10-23 23:04:25

标签: java static constructor final

我基本上想要的是:

public class Test 
{    
   private static final Integer a;

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

}

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

2 个答案:

答案 0 :(得分:11)

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

一个选项是在声明中设置值:

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

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

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成为类的最终实例变量,在构造函数中设置。

答案 1 :(得分: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