web-dev-qa-db-ja.com

コンストラクターで静的な最終フィールドを初期化します

public class A 
{    
    private static final int x;

    public A() 
    {
        x = 5;
    }
}
  • finalは、変数が(コンストラクターで)1回しか割り当てられないことを意味します。
  • staticは、クラスインスタンスであることを意味します。

これが禁止されている理由がわかりません。これらのキーワードは互いにどこで干渉しますか?

80
Yaron Levi

クラスのインスタンスが作成されるたびに、コンストラクターが呼び出されます。したがって、上記のコードは、インスタンスが作成されるたびに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;
    }
}
173
adarshr

静的な最終変数は、クラスがロードされるときに初期化されます。コンストラクターはずっと後に呼び出される場合もあれば、まったく呼び出されない場合もあります。また、コンストラクターは(新しいオブジェクトごとに)複数回呼び出されるため、フィールドは最終的になりません。

静的最終フィールドを初期化するためのカスタムロジックが必要な場合は、静的ブロックに配置します

16

オブジェクトを2回インスタンス化したときに何が起こるかを考えてください。それを再び設定しようとしますが、これは静的ファイナルであることによって明示的に禁止されています。インスタンス全体ではなく、クラス全体に対して一度だけ設定できます。

宣言するときに値を設定する必要があります

private static final x=5;

追加のロジックまたはより複雑なインスタンス化が必要な場合、これは静的初期化ブロックで実行できます。

6
rfeak

staticは、変数がアプリケーション上で一意であることを意味します。 finalは、一度だけ設定する必要があることを意味します。

コンストラクタで設定すると、変数を複数回設定できます。

したがって、直接初期化するか、静的メソッドを提案して初期化する必要があります。

5
ap2cu

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
3
i.am.michiel

考えてみてください。あなたのコードでこれを行うことができます:

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;
    }
}
2
Lukas Eder
    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
  }
}
0
Kush