staticWenn der Modifikator auf eine Variablendeklaration angewendet wird, bedeutet dies, dass die Variable eher eine Klassenvariable als eine Instanzvariable ist. Mit anderen Worten ... es gibt nur eine num1Variable und nur eine num2Variable.
(Abgesehen: eine statische Variable ist wie . Eine globale Variable in einigen anderen Sprachen, mit der Ausnahme , dass sein Name nicht überall sichtbar ist , auch wenn es als deklariert wird public static, ist der unqualifizierte Name nur dann sichtbar , wenn es in der aktuellen Klasse oder eine übergeordneten Klasse deklariert wird oder wenn es mit einem statischen Import importiert wird. Das ist der Unterschied. Ein echtes globales ist ohne Qualifikation irgendwo sichtbar.)
Wenn Sie sich also auf obj.num1und beziehen, beziehen obj.num2Sie sich tatsächlich auf die statischen Variablen, deren tatsächliche Bezeichnungen A.num1und sind A.num2. Und in ähnlicher Weise erhöht der Konstruktor, wenn er inkrementiert num1und num2, dieselben Variablen (jeweils).
Die verwirrende Falte in Ihrem Beispiel liegt in der Klasseninitialisierung. Eine Klasse wird standardmäßig initialisiert, indem zunächst alle statischen Variablen initialisiert und dann die deklarierten statischen Initialisierer (und statischen Initialisiererblöcke) in der Reihenfolge ausgeführt werden, in der sie in der Klasse angezeigt werden . In diesem Fall haben Sie Folgendes:
static A obj = new A();
static int num1;
static int num2=0;
Es passiert so:
Die Statik beginnt mit ihren Standardanfangswerten. A.objist nullund A.num1/ oder A.num2sind Null.
Die erste Deklaration ( A.obj) erstellt eine Instanz von A()und den Konstruktor für AInkremente A.num1und A.num2. Wenn die Deklaration abgeschlossen ist A.num1und A.num2beides 1ist und A.objsich auf die neu erstellte AInstanz bezieht .
Die zweite Deklaration ( A.num1) hat keinen Initialisierer und A.num1ändert sich daher nicht.
Die dritte Deklaration ( A.num2) hat einen Initialisierer, dem Null zugewiesen wird A.num2.
Am Ende der Klasseninitialisierung A.num1ist 1und A.num2ist also 0... und das zeigen Ihre Druckanweisungen.
Dieses verwirrende Verhalten ist darauf zurückzuführen, dass Sie eine Instanz erstellen, bevor die statische Initialisierung abgeschlossen ist, und dass der von Ihnen verwendete Konstruktor von einer noch zu initialisierenden Statik abhängt und diese ändert . Dies sollten Sie in echtem Code vermeiden.