68 votes

Créer un objet de manière statique

Quelqu'un pourrait-il expliquer comment Java exécute ce code? Je veux dire l'ordre d'exécution de chaque déclaration.

 public class Foo
{
    boolean flag = sFlag;
    static Foo foo = new Foo();
    static boolean sFlag = true;

    public static void main(String[] args)
    {
        System.out.println(foo.flag);
    }
}
 

SORTIE:

 false
 

104voto

Jon Skeet Points 692016
  • Classe d'initialisation commence. D'abord, foo est nulle et sFlag est faux
  • La première variable statique de l'initialiseur (foo) s'exécute:
    • Une nouvelle instance de l' Foo est créé
    • La variable d'instance d'initialiseur pour flag exécute actuellement sFlag est faux, alors la valeur de flag est faux
  • La deuxième variable statique de l'initialiseur (sFlag) s'exécute, le réglage de la valeur à true
  • Initialisation de classe complète
  • main s'exécute, impression de l' foo.flag, ce qui est faux

Notez que si sFlag ont été déclarés final , il sera considéré comme une constante à la compilation, à quel point toutes les références à essentiellement, il devait être incorporé à l' true, alors foo.flag serait vrai aussi.

12voto

MByD Points 78505

foo est instancié lors de l'initialisation statique de la classe, et avant sFlag a été initialisé, et la valeur par défaut d'un booléen est faux.

  1. La classe est chargée
  2. Toto est initialisé à l'instance

    2.a Le membre de l'instance drapeau est initialisé à la valeur de sFlag (false par défaut)

  3. sFlag est initialisé à true

Veuillez vous référer à JLS §12.4 pour plus de détails.

5voto

shift66 Points 4964

Lorsque la classe est chargée, les champs sFlag et foo sont initialisés mais les champs foo sont initialisés en premier!
les champs flag et sFlag sont booléens et ne peuvent pas être nuls. Par défaut, ils sont faux et sFlag est toujours faux lorsque foo est en cours d'initialisation. flag = sFlag après cela flag est faux.

2voto

digital_infinity Points 247

L'ordre général d'opérations d'initialisation est (après la classe est chargé et avant la première utilisation):

  1. Statique (de classe) de blocs de code afin qu'il apparaît dans le code,
  2. Objet de blocs de code afin qu'il apparaît dans le code (initialisation des blocs et des devoirs).
  3. Les constructeurs

Certes, je ne vous parle pas des constructeurs et des fonctions du corps comme un bloc de code ci-dessus .

Je ne sais pas comment à propos de final static champs. On dirait qu'ils suivent les règles de static champs et ils ne peuvent pas être référencées avant de déclaration en dépit de précédents commentaires qu'ils sont initialisés à l'étape de compilation. Si ils sont référencés à l'avant il y a une erreur de compilation:

Example.java:8: illegal forward reference
        System.err.println("1st static block j=" + j);

Peut-être final static champs peuvent être initialisés et compilé dans le fichier de classe mais ce n'est pas une règle générale, et ils ne peuvent toujours pas être référencé avant de déclaration.

Exemple de code pour vérifier l'ordre d'initialisation:

class Example {    

    final static int j = 5;

    {
        System.err.println("1st initializer j=" + j);
    }

    static {
        System.err.println("1st static block j=" + j);
    }

    static {
        System.err.println("2nd static block j=" + j);
    }

    final static java.math.BigInteger i = new java.math.BigInteger("1") {    
        {
            System.err.println("final static anonymous class initializer");
        }
    };

    Example() {
        System.err.println("Constructor");
    }

    static {
        System.err.println("3nd static block j=" + j);
    }

    {
        System.err.println("2nd initializer");
    }

    public static void main(String[] args) {
        System.err.println("The main beginning.");
        Example ex = new Example();
        System.err.println("The main end.");
    } 
}

Le code ci-dessus snipset impressions:

1st static block j=5
2nd static block j=5
final static anonymous class initializer
3nd static block j=5
The main beginning.
1st initializer j=5
2nd initializer
Constructor
The main end.

1voto

F M Points 30

au début, les champs statiques doivent être exécutés et au début, en ligne! Donc, en premier lieu, les lignes 4 et 5 seront exécutées de telle sorte que foo soit initialisé en premier et, comme nous le savons, les variables booléennes sont initialisées à false par défaut. ne changera pas de drapeau (il n'y a pas de relation), puis enfin des pistes principales et une impression de falg qui est fausse !!! J'espère être utile! Avoir du succès

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X