Si vous effectuez foo
statique, vous devez l'initialiser dans le constructeur de la classe (ou en ligne où vous définissez) comme les exemples suivants.
Le constructeur de la classe (pas d'exemple):
private static final List foo;
static
{
foo = new ArrayList();
}
En ligne:
private static final List foo = new ArrayList();
Le problème ici n'est pas la façon dont l' final
modificateur œuvres, mais plutôt comment l' static
modificateur de travaux.
L' final
modificateur applique à une initialisation de votre renvoi, par le temps de l'appel à votre constructeur complète (c'est à dire que vous devez l'initialiser dans le constructeur).
Lorsque vous initialisez un attribut en ligne, il est initialisé avant le code que vous avez définis pour le constructeur est exécuté, de sorte que vous obtenez les résultats suivants:
- si
foo
est static
, foo = new ArrayList()
sera exécuté avant l' static{}
constructeur, vous avez défini pour votre classe est exécutée
- si
foo
n'est static
, foo = new ArrayList()
sera exécuté avant votre constructeur est exécuté
Lorsque vous n'avez pas initilize un attribut en ligne, final
modificateur applique que si vous initialisez et que vous devez le faire dans le constructeur. Si vous aussi vous avez un static
modificateur, le constructeur, vous devrez initialiser l'attribut dans la classe' l'initialisation du bloc : static{}
.
L'erreur que vous obtenez dans votre code est le fait qu' static{}
est exécuté lorsque la classe est chargée, avant le moment d'instancier un objet de cette classe. Ainsi, vous n'avez pas initialisé foo
lorsque la classe est créée.
Pensez à l' static{}
bloc comme un constructeur pour un objet de type Class
. C'est là que vous devez effectuer l'initialisation de votre static final
attributs de classe (si pas fait inline).
Note de côté:
L' final
modificateur assure const-ness seulement pour les types primitifs et les références.
Lorsque vous déclarez une final
de l'objet, ce que vous obtenez est un final
de référence pour cet objet, mais l'objet lui-même n'est pas constante.
Ce que vous êtes vraiment à atteindre lors de la déclaration d'un final
attribut est que, une fois que vous déclarez un objet pour votre but précis (comme l' final List
que vous avez déclaré), et uniquement à cet objet sera utilisé à cette fin: vous ne serez pas en mesure de changer de List foo
autre List
, mais vous pouvez toujours modifier votre List
par l'ajout/suppression d'éléments ( List
vous utilisez sera le même, seule avec son contenu modifié).