简体   繁体   English

在构造函数中初始化一个静态 final 字段

[英]Initialize a static final field in the constructor

public class A 
{    
    private static final int x;

    public A() 
    {
        x = 5;
    }
}
  • final means the variable can only be assigned once (in the constructor). final意味着变量只能被赋值一次(在构造函数中)。
  • static means it's a class instance. static意味着它是一个类实例。

I can't see why this is prohibited.我不明白为什么禁止这样做。 Where do those keywords interfere with each other?这些关键字在哪里相互干扰?

A constructor will be called each time an instance of the class is created.每次创建类的实例时都会调用构造函数。 Thus, the above code means that the value of x will be re-initialized each time an instance is created.因此,上面的代码意味着每次创建实例时都会重新初始化 x 的值。 But because the variable is declared final (and static), you can only do this但是因为变量被声明为最终的(和静态的),你只能这样做

class A {    
    private static final int x;

    static {
        x = 5;
    }
}

But, if you remove static, you are allowed to do this:但是,如果您删除静态,您可以这样做:

class A {    
    private final int x;

    public A() {
        x = 5;
    }
}

OR this:或这个:

class A {    
    private final int x;

    {
        x = 5;
    }
}

static final variables are initialized when the class is loaded.静态最终变量在类加载时初始化。 The constructor may be called much later, or not at all.构造函数可能会在很晚之后被调用,或者根本不会被调用。 Also, the constructor will be called multiple times (with each new object ), so the field could no longer be final.此外,构造函数将被多次调用(每个新对象),因此该字段不再是最终的。

If you need custom logic to initialize your static final field, put that in a static block如果您需要自定义逻辑来初始化静态最终字段,请将其放在静态块中

Think about what happens the second time you instantiate an object.想想第二次实例化一个对象时会发生什么。 It tries to set it AGAIN, which is expressly prohibited by being a static final.它试图再次设置它,这是静态最终明确禁止的。 It can only be set one time for the entire class, not instance.它只能为整个类设置一次,而不是实例。

You should set the value when you declare it您应该在声明时设置该值

private static final x=5;

If you need additional logic, or more complex instantiation, this can be done in a static initializer block.如果您需要额外的逻辑,或更复杂的实例化,这可以在静态初始化块中完成。

static means that the variable is unique on the application. static意味着该变量在应用程序中是唯一的。 final means that it should be set only once. final意味着它应该只设置一次。

If you set it in your constructor, you allow to set the variable more than once.如果在构造函数中设置它,则允许多次设置变量。

Hence you should intialize it directly or propose a static method to initialize it.因此,您应该直接初始化它或提出一个静态方法来初始化它。

Final doesn't mean that is has to be initialized in the constructor. Final并不意味着必须在构造函数中初始化。 Generally this is what is done :通常这是这样做的:

 private static final int x = 5;

static instead means that the variable will be shared through multiple instances of the class.静态意味着该变量将通过类的多个实例共享。 For example :例如 :

public class Car {
   static String name;
   public Car(String name) {
      this.name = name;
   }
}

...

Car a = new Car("Volkswagen");
System.out.println(a.name); // Produces Volkswagen

Car b = new Car("Mercedes");
System.out.println(b.name); // Produces Mercedes
System.out.println(a.name); // Produces Mercedes

Think about it.想想看。 You could do this with your code:你可以用你的代码做到这一点:

A a = new A();
A b = new A(); // Wrong... x is already initialised

The correct ways to initialise x are:初始化 x 的正确方法是:

public class A 
{    
    private static final int x = 5;
}

or或者

public class A 
{    
    private static final int x;

    static
    {
        x = 5;
    }
}

Static静止的

The keyword static means that a member of an object, in this case a field, is not tied to an instance of a class, but is a member of the class instead.关键字static意味着对象的成员,在这种情况下是字段,不绑定到类的实例,而是类的成员。 If the static member is a field, it is initialised during loading of a class.如果静态成员是一个字段,则在加载类期间对其进行初始化。

It is accessible through the class rather than through an instance (though the latter is not impossible, it is considered bad form), so it is accessible without the constructor having ran at all — ever.它可以通过类而不是通过实例访问(尽管后者并非不可能,但它被认为是糟糕的形式),因此它可以在根本没有运行构造函数的情况下访问 - 永远。

Final最终的

The keyword final , when applied to a field of an object, means that it can be assigned to only once, and that it has to be assigned to during initialisation.关键字final ,当施加到物体的领域中,装置,它可被分配给仅一次,并且它具有初始化期间被分配给。

Static Final静态决赛

Taken together, these two keywords effectively define a constant: it can be assigned to only once, has to be assigned to, and is the same for all instances of that class.总之,这两个关键字有效地定义常量:它可以被分配到只有一次,必须分配方式,是该类的所有实例相同。

Since the static field is initialised during class loading, it has to be initialised then, either at declaration, or in a static initialiser block.由于静态字段是在类加载期间初始化的,因此必须在声明时或在静态初始化程序块中对其进行初始化。

This means that if and when you reach the constructor, it will already have been initialised, because it needed to already have been initialised.这意味着当你到达构造函数时,它已经被初始化,因为它需要已经被初始化。

Singleton单身人士

If you're looking for a class member that you only assign to once, but read many times, you're dealing with a singleton .如果您正在寻找只分配给一次但阅读多次的班级成员,那么您正在处理单例 The singleton pattern is commonly used for access to a shared resource.单例模式通常用于访问共享资源。

The field is made static but not final;该字段是静态的,但不是最终的; instead when accessing the field, the code checks whether it has been initialised already, if not, it is done then and there.相反,在访问该字段时,代码会检查它是否已经初始化,如果没有,则在当时和那里完成。 Note that in environments with multiple threads, you need to synchronise access to the field, to avoid accessing it while it is initialising.请注意,在具有多个线程的环境中,您需要同步对字段的访问,以避免在初始化时访问它。

    public class StaticFinalExample {
  /*
   * Static final fields should be initialized either in
   * static blocks or at the time of declaration only
   * Reason : They variables are like the utility fields which should be accessible
   * before object creation only once.
   */
  static final int x;

  /*
   * Final variables shuould be initialized either at the time of declaration or
   * in initialization block or constructor only as they are not accessible in static block
   */
  final int y;

  /*
   * Static variables can be initialized either at the time of declaration or
   * in initialization or constructor or static block. Since the default value is given to the
   * static variables by compiler, so it depends on when you need the value
   * depending on that you can initialize the variable appropriately
   * An example of this is shown below in the main method
   */
  static int z;

  static {
    x = 20; // Correct
  }
  {
    y = 40; // Correct
  }
  StaticFinalExample() {
    z = 50; // Correct
  }
  public static void main (String args[]) {
    System.out.println("Before Initialization in Constructor" + z);   // It will print 0
    System.out.println("After Initializtion in Constructor" + new StaticFinalExample().z); // It will print 50
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM