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 SubClassreturn 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.
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
Fichier de classe dejavap -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
Fichier de classe deSubClass
Expliquez grossièrement le contenu (si le sujet est intéressé parSuperClass
, vous pouvez lire le cahier des charges
JVM指令集
, qui a une explication très détaillée).JVM
La 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 deApp
dans l'App 2. Accédez au constructeur de调用App的构造函数
, initialisez d'abord la classe parent, correspondant à
App
Object
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 àSubClass
5 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 àSubClass
7 dans la sous-classe. Le constructeur构造函数
exécute initialement le constructeur de, correspondant à
SubClass
SuperClass
8 dans SubClass. Exécutez le code print dans le constructeur dans调用SuperClass的构造函数
Quittez "Get string construction SuperClass"9.
SuperClass
Construction terminéeAllez à la position du code en 7, continuez à exécuter
SuperClass
code restantreturn
10. Exécutez le code du constructeur dansSubClass
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 dansApp
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
App
14. Exécutez la méthode dans le bloc statique et autorisez "3"return
15 .Entrez la méthode de saisieet imprimez « Bonjour »
main
Le 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.