2012-07-20 4 views
3

Je le trouve tuff avec enums. Ceci est un exemple du livre de Kathy Siera:Enums constructeur initialiseur statique

public class WeatherTest { 

    static Weather w; 

    public static void main(String[] args) { 
     System.out.print(w.RAINY.count + " " + w.Sunny.count + " "); 
    } 
} 

enum Weather { 

    RAINY, Sunny; 
    int count = 0; 

    Weather() { 
     System.out.print("c "); 
     count++; 
    } 
} 

La sortie est c c 1 1. Compris. Maintenant je pensais que si le champ de compte était statique? Est-ce que la sortie serait c 2 2? Basé sur cela, j'ai modifié la variable de compte à statique. Mais ce que je vois est ceci: Erreur de compilation: Référence illégale au champ statique de l'initialiseur.

Recherche sur le net J'ai trouvé que c'était une sorte de trou de boucle de Sun et il permet des méthodes statiques qui peuvent changer les champs statiques. Ok .. Alors maintenant, j'utilise une INCR méthode statique pour faire mon travail:

 class WeatherTest { 

    static Weather w; 

    public static void main(String[] args) { 
     System.out.print(w.RAINY.count + " " + w.Sunny.count + " "); 
    } 
} 

enum Weather { 

    RAINY, Sunny; 

    Weather() { 
     System.out.print("c "); 
     incr(); 
    } 
    static int count = 0; 

    static void incr() { 
     count++; 
    } 
} 

À ma grande surprise, je reçois la sortie: c c 0 0! Quelqu'un peut-il m'expliquer ce comportement avant de me tirer dessus?

+0

S'il vous plaît fixer votre indentation et accolades. – ardent

+0

Extrêmement tuff question! Tous les programmeurs Java, Armure vous-même :) – Kameron

+0

ardentsonata: Bien sûr – user1500024

Répondre

5

Les valeurs enum peuvent être considérées comme des champs statiques glorifiés (ils sont sous les couvertures).

Donc, si votre Weather était une classe régulière Java, il aurait été quelque chose comme ceci:

class Weather { 
    public final static Weather RAINY = new Weather(); 
    public final static Weather Sunny = new Weather(); 

    static int count = 0; 

    Weather() { 
    System.out.print("c "); 
    incr(); 
    } 

    static void incr() 
    { 
     count++; 
    } 
} 

Vous pouvez voir que count est déclaré APRÈS les deux valeurs ENUM, cela signifie qu'il est également initialisé après la création des deux valeurs. En outre, chaque appel de fonction qui rencontre une variable statique non initialisée le traite comme initialisé avec la valeur par défaut (pour int c'est 0).

Parce que vous appelez jamais incr après count a été correctement initialisé, vous voyez sa valeur comme toujours 0

+0

Je suis d'accord avec la séquence d'exécution, mais une partie confus mon lors de l'exécution de ce code est, au deuxième appel , Incr() méthode montrant le compte comme «2». Selon votre théorie, il devrait être compté comme ZÉRO, n'est-ce pas? – kosa

+0

Je suis partiellement clair; Pouvez-vous nous en dire plus sur ce qui se passe quand incr() est rencontré dans le constructeur Weather()? Pourquoi cela ne résulte-t-il pas en une sorte d'erreur ou d'exception de compilateur puisque nous essayons d'incrémenter une valeur qui n'est pas encore initialisée? – user1500024

+0

@thinksteep. Lors d'un premier appel à 'incr'' count' n'est pas initialisé, de sorte que la valeur par défaut de '0' est attribuée à l'emplacement de mémoire. Puis il est incrémenté 2 fois par les constructeurs, alors l'initialisation REAL à '0 'se produit. –

Questions connexes