web-dev-qa-db-fra.com

Initialiser un champ final statique dans le constructeur

public class A 
{    
    private static final int x;

    public A() 
    {
        x = 5;
    }
}
  • final signifie que la variable ne peut être affectée qu'une seule fois (dans le constructeur).
  • static signifie que c'est une instance de classe.

Je ne vois pas pourquoi c'est interdit. Où ces mots-clés interfèrent-ils les uns avec les autres?

79
Yaron Levi

Un constructeur sera appelé chaque fois qu'une instance de la classe est créée. Ainsi, le code ci-dessus signifie que la valeur de x sera réinitialisée chaque fois qu'une instance est créée. Mais comme la variable est déclarée finale (et statique), vous ne pouvez le faire que

class A {    
    private static final int x;

    static {
        x = 5;
    }
}

Mais, si vous supprimez de la statique, vous êtes autorisé à le faire:

class A {    
    private final int x;

    public A() {
        x = 5;
    }
}

Ou ca:

class A {    
    private final int x;

    {
        x = 5;
    }
}
169
adarshr

les variables finales statiques sont initialisées lorsque la classe est chargée. Le constructeur peut être appelé beaucoup plus tard, ou pas du tout. En outre, le constructeur sera appelé plusieurs fois (avec chaque nouvel objet), de sorte que le champ ne peut plus être final.

Si vous avez besoin d’une logique personnalisée pour initialiser votre champ final statique, placez-le dans un bloc statique.

16
Sean Patrick Floyd

Pensez à ce qui se passe la deuxième fois que vous instanciez un objet. Il essaie de le remettre à zéro, ce qui est expressément interdit en tant que finale statique. Il ne peut être défini qu'une seule fois pour toute la classe, et non par instance.

Vous devez définir la valeur lorsque vous le déclarez

private static final x=5;

Si vous avez besoin d'une logique supplémentaire ou d'une instanciation plus complexe, vous pouvez le faire dans un bloc d'initialisation statique.

6
rfeak

static signifie que la variable est unique sur l'application .final signifie qu'elle ne devrait être définie qu'une seule fois.

Si vous le définissez dans votre constructeur, vous autorisez à définir la variable plusieurs fois.

Par conséquent, vous devez l’initialiser directement ou proposer une méthode statique pour l’initialiser.

5
ap2cu

Final ne signifie pas que cela doit être initialisé dans le constructeur. En général, voici ce qui est fait: 

 private static final int x = 5;

static signifie plutôt que la variable sera partagée via plusieurs instances de la classe. Par exemple : 

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

Penses-y. Vous pouvez le faire avec votre code:

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

Les manières correctes d'initialiser x sont:

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

ou

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