Pourquoi une variable finale doit-elle être initialisée avant la fin du constructeur?
public class Ex { final int q; }
Quand je comstack ce code je reçois une erreur comme ça
err: la variable q n’a peut-être pas été initialisée
La raison officielle est qu’elle est définie par la spécification de langage Java 8.3.1.2 :
Une variable d’instance finale vide doit être définitivement affectée à la fin de chaque constructeur de la classe dans laquelle elle est déclarée; sinon, une erreur de compilation survient.
Une finale vide est une variable finale dont la déclaration manque d’initialiseur (c’est-à-dire ce que vous décrivez).
Parce que final
vous empêche de modifier les variables, il doit être initialisé à un moment donné et le constructeur est le bon endroit pour le faire.
Dans votre cas, il s’agirait d’une finale vierge car elle n’est pas initialisée lorsqu’elle est déclarée.
La valeur d’une variable final
ne peut être définie qu’une seule fois. Le constructeur est le seul endroit dans le code pour une classe que vous pouvez garantir que cela sera vrai; le constructeur n’est appelé qu’une seule fois pour un object, mais d’autres méthodes peuvent être appelées n’importe quel nombre de fois.
Une variable final
doit être initialisée à la déclaration ou dans un constructeur.
S’il n’a pas été initialisé lors du retour du constructeur, il se peut qu’il ne soit jamais initialisé et qu’il rest une variable non initialisée. Le compilateur ne peut pas prouver qu’il sera initialisé et génère donc une erreur.
Cet extrait de Wikipedia l’ explique bien:
Une variable finale ne peut être initialisée qu’une seule fois, via un initialiseur ou une instruction d’affectation. Il n’est pas nécessaire de l’initialiser au moment de la déclaration: il s’agit d’une variable “vierge finale”. Une variable d’instance finale vierge d’une classe doit être définitivement affectée à la fin de chaque constructeur de la classe dans laquelle elle est déclarée; de même, une variable statique finale vierge doit être définitivement affectée dans un initialiseur statique de la classe dans laquelle elle est déclarée: sinon, une erreur de compilation survient dans les deux cas. (Remarque: si la variable est une référence, cela signifie que la variable ne peut pas être liée à un autre object. Mais l’object auquel elle fait référence est toujours modifiable, s’il était modifiable à l’origine.)
Le final
mot clé appliqué à un champ a l’un des deux effets suivants:
final HashMap a
, vous ne pourrez le définir qu’une seule fois et vous ne pourrez pas le this.a=new HashMap();
encore une fois, mais rien ne vous empêche de faire this.a.put("a","b")
, s puisque cela ne modifie pas la référence, seulement le contenu de l’object. Le final
modificateur vous empêche de modifier la valeur des variables, vous devez donc l’initialiser à l’endroit où vous le déclarez.
La spécification de langue contient des garanties spécifiques sur les propriétés des variables et des champs finaux. L’une d’elles est qu’un object correctement construit (c’est-à-dire dont le constructeur a abouti) doit avoir tous ses champs d’instance finaux initialisés et visibles pour tous les threads. Ainsi, le compilateur parsing les chemins de code et vous oblige à initialiser ces champs.
Final modifier
ne permet pas de change your variable value
. Vous devez donc lui atsortingbuer une valeur à un endroit donné et le constructor
est l’endroit où vous devez le faire dans ce cas.