7
votes

Initialisation des champs finaux statiques en Java

public class Main {
 static final int alex=getc();
 static final int alex1=Integer.parseInt("10");
 static final int alex2=getc();

public static int getc(){
    return alex1;
}

public static void main(String[] args) {
    final Main m = new Main();
    System.out.println(alex+" "+alex1 +" "+alex2);
  } 
}
Can someone tell me why this prints: 0 10 10? I understand that it's a static final variable and its value shouldn't change but it`s a little difficult to understand how the compiler initializes the fields.

0 commentaires

5 Réponses :


6
votes

C'est un problème de commande. Les champs statiques sont initialisés dans l'ordre dans lequel elles sont rencontrées, alors lorsque vous appelez GETC () à initialiser la variable Alex, Alex1 n'a pas encore été définie. Vous devez d'abord mettre l'initialisation d'Alex1, puis vous obtiendrez le résultat attendu.


6 commentaires

C'était une question d'entrevue non vraiment un problème et j'essayais de comprendre pourquoi le compilateur attribue 0 juste parce que le champ Alex1 n'a pas encore été initialisé. Parce que Alex1 est final et Alex prend la place de Alex1 = >> Alex1 est 0?


Les affectations statiques sont différentes des variables des membres et n'ont aucune garantie de ce type. Chaque affectation statique est évaluée afin que le chargeur de classe le trouve. Donc, dans votre cas, il attribue d'abord Alex en appelant GETC (). À ce stade, Alex1 n'a pas encore été initialisé, de sorte que 0 est renvoyé.


ok, thx.Anuher question .. S'il est initialisé dans un bloc statique, le champ Alex1, avec la valeur 10, qu'est-ce que les autres imprimeraient? Lequel est exécuté en premier? le bloc statique ou l'initialisation?


@Alexx, il est toujours initialisé dans l'ordre qu'il apparaît. Où vous placez que le bloc statique est tout ce qui compte.


Encore une fois, cela dépend de la commande. Votre finale statique int alex1 = integer.parseint ("10"); est vraiment un raccourci pour un bloc statique et sera transformé en même par le compilateur.


@stevevis - En fait, ce n'est pas le chargeur de classe qui le fait, c'est le mécanisme d'initialisation de la classe intrinsèque. (L'initialisation réelle est effectuée par les classes "" pseudo-méthode.)



0
votes

Les variables de classe ne sont pas nécessaires pour initialiser, elles sont automatiquement définies sur leurs valeurs par défaut. Si les primitives (comme int, courte ...), il est 0 (zéro) pour les objets c'est null . Par conséquent, Alex1 est défini sur 0. Les variables de méthode doivent être initialisées, sinon vous obtiendrez une erreur de compilation.

Pour une meilleure explication Lire http://download.oracle.com /javase/tatutorial/java/javaoo/classvars.html


1 commentaires

Oui, mais les champs finaux doivent toujours être initialisés lors de la compilation ou de l'exécution avant la création de l'objet. Ce que vous SEDIID s'applique aux champs normaux non finaux.ps Il fonctionne et je dis avant qu'il n'imprime 0 10 10



4
votes

champs finaux statiques dont les valeurs ne sont pas des expressions constantes du temps compilé sont initialisées par ordre de déclaration. Ainsi, lorsque alex en étant initialisé, alex1 n'est pas encore initialisé, de sorte que getc () renvoie les valeurs par défaut de alex1 ( 0 ).

Notez que le résultat sera différent ( 10 10 10 10 ) dans le cas suivant: xxx

Dans ce cas, Alex1 est initialisé par une expression constante de la compilation, elle est donc initialisée depuis le début.


1 commentaires

+1 pour les expressions constantes de la compilée. (Pourquoi sinon integer.parseint ?)



2
votes

Il n'y a rien de spécial sur les champs statiques, il ne suffit que le compilateur ne peut pas entraîner d'entraînement que vous utilisez une méthode qui peut accéder à un champ avant son initialisée.

par exemple xxx p> impressions xxx


0 commentaires

5
votes

Cette situation est couverte par JLS 8.3. 2.3 "Restrictions sur l'utilisation de champs lors de l'initialisation".

Les règles JLS permettent à l'utilisation de votre question et indiquez que le premier appel à getc () code> retournera par défaut ( une valeur nonInialisée) de alex code>. p>

Cependant, les règles interdisent certaines utilisations de variables non initialisées; E.g. P>

int i = j + 1;
int j = i + 1;


0 commentaires