Résumé: à la Fois les initialiseurs d'accéder à un champ c'est pas encore initialisé (et donc encore a la valeur par défaut de zéro). Puisque c'est probablement une erreur de programmation, le langage des interdictions de certaines des formes simples d'accès. Cependant, il n'a pas d'interdiction de forme plus complexe.
Le comportement est conforme à la JLS, spécialement §8.3.2.3. Restrictions sur l'utilisation de Champs lors de l'Initialisation
La déclaration d'un membre doit apparaître sous forme de texte avant de l'utiliser seulement si le membre est une instance (respectivement static
) champ d'une classe ou d'une interface C
et de toutes les conditions suivantes s'appliquent:
L'utilisation se produit dans une instance (respectivement static
) de la variable d'initialiseur de C ou dans une instance (respectivement static
) de l'initialiseur de C.
L'utilisation n'est pas sur le côté de main gauche d'une affectation.
L'utilisation se fait via un simple nom.
C
le plus proche du centre de la classe ou de l'interface en joignant l'utilisation.
Le premier exemple qui répond à tous les quatre conditions et est donc invalide. Le deuxième exemple n'est pas satisfaire à la troisième condition (this.x
n'est pas un simple nom), et est donc OK.
L'ensemble de la séquence des événements est la suivante:
Ainsi, si un initialiseur fait référence à un domaine qui apparaît plus loin dans la définition de la classe (ou du champ lui-même), il serait de voir la valeur par défaut de cet autre champ. C'est probablement une erreur de programmation et est donc explicitement interdites par le §8.3.2.3.
Si vous contourner §8.3.2.3, par exemple, à l'aide de this.
vers l'avant et le faire référence à un champ, vous verrez la valeur par défaut (zéro pour int
). Ainsi, la suite est bien définie et est garanti pour définir x
de 42
:
class test {
int x = this.x + 42;
}