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

7z5jn7bk  于 2023-05-05  发布在  Java
关注(0)|答案(8)|浏览(146)
public class A 
{    
    private static final int x;

    public A() 
    {
        x = 5;
    }
}
  • final表示变量只能赋值一次(在构造函数中)。
  • static表示它是一个类示例。

我不明白为什么这是被禁止的。这些关键词在哪里相互干扰?

gwbalxhn

gwbalxhn1#

每次创建类的示例时都将调用构造函数。因此,上面的代码意味着每次创建一个示例时,x的值都将被重新初始化。但是因为变量被声明为final(和static),所以只能这样做

class A {    
    private static final int x;

    static {
        x = 5;
    }
}

但是,如果你删除静态,你可以这样做:

class A {    
    private final int x;

    public A() {
        x = 5;
    }
}

或者这个:

class A {    
    private final int x;

    {
        x = 5;
    }
}
dojqjjoe

dojqjjoe2#

静态final变量在类被加载时被初始化。构造函数可能会在很久以后被调用,或者根本不被调用。此外,构造函数将被多次调用(对于每个新对象),因此该字段不再是final。
如果需要自定义逻辑来初始化静态final字段,请将其放在静态块中

z9smfwbn

z9smfwbn3#

想想第二次示例化一个对象时会发生什么。它试图设置它AGAIN,这是明确禁止的静态final。它只能为整个类设置一次,而不能为示例设置。
您应该在声明该值时设置它

private static final x=5;

如果需要额外的逻辑,或者更复杂的示例化,可以在静态初始化器块中完成。

9rnv2umw

9rnv2umw4#

static表示变量在应用程序中是唯一的。final意味着它应该只设置一次。
如果你在构造函数中设置了它,你就可以多次设置这个变量。
因此,您应该直接初始化它或提出一个静态方法来初始化它。

gzjq41n4

gzjq41n45#

想想吧你可以用你的代码做到这一点:

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

初始化x的正确方法是:

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

public class A 
{    
    private static final int x;

    static
    {
        x = 5;
    }
}
wecizke3

wecizke36#

Final并不意味着必须在构造函数中初始化。通常是这样做的:

private static final int x = 5;

static表示变量将通过类的多个示例共享。例如:

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
hyrbngr7

hyrbngr77#

静态

关键字static意味着对象的成员,在本例中是字段,不绑定到类的示例,而是类的一般成员。如果静态成员是一个字段,它在类的加载过程中初始化。
它可以通过类而不是通过示例访问(尽管后者不是不可能的,但它被认为是糟糕的形式),因此它可以在根本没有构造函数运行的情况下访问-永远。

最终

关键字final,当应用于对象的字段时,意味着它只能被分配一次,并且它必须在初始化期间被分配。

静态最终

这两个关键字一起有效地定义了一个常量:它只能被赋值一次,* 必须被赋值,并且对于该类的所有示例都是相同的。
由于静态字段是在类加载期间初始化的,因此必须在声明或静态初始化器块中初始化它。
这意味着,如果你到达构造函数,它将已经被初始化,因为它 * 需要 * 已经被初始化。

单例

如果您正在寻找一个只赋值一次,但读取多次的类成员,那么您正在处理a singleton。单例模式通常用于访问共享资源。
字段被设置为静态的,但不是最终的;相反,当访问该字段时,代码检查它是否已经被初始化,如果没有,则在那里进行初始化。请注意,在多线程环境中,您需要同步对字段的访问,以避免在初始化时访问它。

bybem2ql

bybem2ql8#

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
  }
}

相关问题