java-se - Java:请问这段代码的执行顺序是怎么样的,如果能够详细点更好,谢谢
PHPz
PHPz 2017-04-18 10:36:29
0
2
356
PHPz
PHPz

学习是最好的投资!

répondre à tous(2)
小葫芦

Variables de classe (variables statiques)>Blocs statiques>Méthodes de construction>Variables membres ordinaires>Sauf statique pour les sous-classes. Toutes les modifications statiques en JAVA alloueront de l'espace au moment de la compilation, et les objets ne seront alloués que lorsqu'ils seront utilisés, c'est-à-dire que lorsque new est utilisé, lorsqu'une sous-classe hérite d'une classe parent, elle doit évidemment d'abord être allouée à la classe parent. un fils peut-il naître sans père, n'est-ce pas ?

迷茫

Le sujet peut aider à comprendre le processus d'initialisation en décompilant le class fichier compilé.

La commande javap -l -c -p -v App dans la ligne de commande obtiendra le contenu décompilé après exécution. Analysons-le brièvement en fonction du code source donné par le questionneur :
Ce qui suit montre une partie du contenu décompilé lié à l'initialisation
App

private static com.real.test.App d;
  descriptor: Lcom/real/test/App;
  flags: ACC_PRIVATE, ACC_STATIC

private com.real.test.SubClass t;
  descriptor: Lcom/real/test/SubClass;
  flags: ACC_PRIVATE

static {};
  descriptor: ()V
  flags: ACC_STATIC
  Code:
    stack=2, locals=0, args_size=0
       0: new           #1                  // class com/real/test/App
       3: dup
       4: invokespecial #12                 // Method "<init>":()V  **调用App的构造函数**
       7: putstatic     #15                 // Field d:Lcom/real/test/App;
      10: getstatic     #17                 // Field java/lang/System.out:Ljava/io/PrintStream;
      13: iconst_3   **得到数字常量3**
      14: invokevirtual #23                 // Method java/io/PrintStream.println:(I)V   **打印数字常量3**
      17: return
    LineNumberTable:
      line 4: 0
      line 8: 10
      line 3: 17
    LocalVariableTable:
      Start  Length  Slot  Name   Signature

com.real.test.App();   **构造函数详细内容**
  descriptor: ()V
  flags:
  Code:
    stack=3, locals=1, args_size=1
       0: aload_0
       1: invokespecial #31                 // Method java/lang/Object."<init>":()V   **调用Object的构造函数**
       4: aload_0
       5: new           #32                 // class com/real/test/SubClass
       8: dup
       9: invokespecial #34                 // Method com/real/test/SubClass."<init>":()V   **调用SubClass的构造函数**
      12: putfield      #35                 // Field t:Lcom/real/test/SubClass;
      15: getstatic     #17                 // Field java/lang/System.out:Ljava/io/PrintStream;
      18: iconst_4   **得到数字常量4**
      19: invokevirtual #23                 // Method java/io/PrintStream.println:(I)V   **打印数字常量4**
      22: return
    LineNumberTable:
      line 11: 0
      line 5: 4
      line 12: 15
      line 13: 22
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0      23     0  this   Lcom/real/test/App;

public static void main(java.lang.String[]);
  descriptor: ([Ljava/lang/String;)V
  flags: ACC_PUBLIC, ACC_STATIC
  Code:
    stack=2, locals=1, args_size=1
       0: getstatic     #17                 // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #40                 // String Hello  **得到字符串Hello**
       5: invokevirtual #42                 // Method java/io/PrintStream.println:(Ljava/lang/String   **打印字符串**
       8: return
    LineNumberTable:
      line 16: 0
      line 17: 8
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0       9     0  args   [Ljava/lang/String;
Fichier de classe de

SubClass

static {};  **静态块**
  descriptor: ()V
  flags: ACC_STATIC
  Code:
    stack=2, locals=0, args_size=0
       0: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: iconst_1   **得到数字常量1**
       4: invokevirtual #14                 // Method java/io/PrintStream.println:(I)V   **打印数字常量1**
       7: return
    LineNumberTable:
      line 28: 0
      line 26: 7
    LocalVariableTable:
      Start  Length  Slot  Name   Signature

public com.real.test.SubClass();  **构造函数**
  descriptor: ()V
  flags: ACC_PUBLIC
  Code:
    stack=2, locals=1, args_size=1
       0: aload_0
       1: invokespecial #23                 // Method com/real/test/SuperClass."<init>":()V   **调用SuperClass的构造函数**
       4: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
       7: iconst_2   **得到数字常量2**
       8: invokevirtual #14                 // Method java/io/PrintStream.println:(I)V   **打印数字常量2**
      11: return
    LineNumberTable:
      line 31: 0
      line 32: 4
      line 33: 11
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0      12     0  this   Lcom/real/test/SubClass;
Fichier de classe de

SuperClass

 com.real.test.SuperClass();
   descriptor: ()V
   flags:
   Code:
     stack=2, locals=1, args_size=1
        0: aload_0
        1: invokespecial #8                  // Method java/lang/Object."<init>":()V   **Object的构造函数**
        4: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;
        7: ldc           #16                 // String 构造SuperClass   **得到字符串构造SuperClass**
        9: invokevirtual #18                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V   **打印字符串**
       12: return
     LineNumberTable:
       line 21: 0
       line 22: 4
       line 23: 12
     LocalVariableTable:
       Start  Length  Slot  Name   Signature
           0      13     0  this   Lcom/real/test/SuperClass;
Expliquez grossièrement le contenu (si le sujet est intéressé par

, vous pouvez lire le cahier des charges JVM指令集, qui a une explication très détaillée). JVMLa partie marquée d'un astérisque dans le contenu décompilé ci-dessus est l'annotation que j'ai ajoutée. Selon l'ordre d'exécution du code :
1. JVM charge la classe
, les variables statiques de App seront initialisées à ce moment, correspondant au bytecode de App dans l'App 2. Accédez au constructeur de 调用App的构造函数, initialisez d'abord la classe parent
, correspondant à AppObject dans l'application 3. Initialisez les variables d'instance 调用Object的构造函数, correspondant à
SubClass dans l'application 4. À ce stade, 调用SubClass的构造函数 doit être chargé en première classe, lors de l'initialisation des variables statiques et de l'exécution des blocs statiques, correspondant à
SubClass5 dans la sous-classe. À ce moment, l'exécution du code dans 静态块 imprime ". 1"
6. Exécuter le constructeur après le chargement de SubClass. , correspondant à
SubClass7 dans la sous-classe. Le constructeur 构造函数 exécute initialement le constructeur de
, correspondant à SubClassSuperClass8 dans SubClass. Exécutez le code print dans le constructeur dans 调用SuperClass的构造函数 Quittez "Get string construction SuperClass"
9. SuperClass Construction terminée
Allez à la position du code en 7, continuez à exécuter SuperClass code restant return 10. Exécutez le code du constructeur dans SubClass pour imprimer la sortie "2"
11. Après avoir exécuté le SubClass constructeur
à l'emplacement du code en 3, continuez à exécuter le code restant dans SubClass return 12. Exécutez le code du constructeur dans App et imprimez " 4"
13. Après avoir exécuté le constructeur App de
, allez à la position du code en 1 et continuez l'initialisation. les variables statiques App14. Exécutez la méthode dans le bloc statique et autorisez "3" return15 .Entrez la méthode de saisie
et imprimez « Bonjour »
mainLe processus ci-dessus est la séquence d'exécution approximative.

Le contenu de la réponse peut être un peu déroutant. Si vous ne comprenez pas quelque chose, vous pouvez me le demander.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!