To, co staticoznacza modyfikator, gdy jest stosowany do deklaracji zmiennej, to fakt, że zmienna jest zmienną klasy, a nie zmienną instancji. Innymi słowy ... jest tylko jedna num1zmienna i tylko jedna num2zmienna.
(Poza tym: zmienna statyczna jest podobna do zmienna globalna w niektórych innych językach, z tą różnicą, że jej nazwa nie jest widoczna wszędzie. Nawet jeśli jest zadeklarowana jako a public static, niekwalifikowana nazwa jest widoczna tylko wtedy, gdy jest zadeklarowana w bieżącej klasie lub nadklasie lub jeśli jest importowany przy użyciu importu statycznego. Na tym polega różnica. Prawdziwy globalny jest wszędzie widoczny bez kwalifikacji).
Więc kiedy odnoszą się do obj.num1i obj.num2, w rzeczywistości odnosi się do tych zmiennych statycznych, których nazwy są prawdziwe A.num1i A.num2. I podobnie, gdy konstruktor zwiększa wartość num1inum2 , zwiększa te same zmienne (odpowiednio).
Myląca kwestia w twoim przykładzie dotyczy inicjalizacji klasy. Klasa jest inicjowana przez pierwszą domyślną inicjalizację wszystkich zmiennych statycznych, a następnie wykonywanie zadeklarowanych inicjatorów statycznych (i bloków inicjatorów statycznych) w kolejności, w jakiej pojawiają się w klasie. W tym przypadku masz to:
static A obj = new A();
static int num1;
static int num2=0;
Dzieje się tak:
Statyka zaczyna się od domyślnych wartości początkowych; A.objjest nulli A.num1/ A.num2są zerem.
Pierwsza deklaracja ( A.obj) tworzy wystąpienie A()i konstruktor dla Ainkrementacji A.num1i A.num2. Gdy deklaracja zakończy się, A.num1i A.num2są oba 1, i A.objodwołuje się do nowo utworzonego Awystąpienia.
Druga deklaracja ( A.num1) nie ma inicjatora, więc A.num1się nie zmienia.
Trzecia deklaracja ( A.num2) ma inicjator, który przypisuje zero do A.num2.
Tak więc pod koniec inicjalizacji klasy A.num1jest 1i A.num2jest0 ... i to właśnie pokazują twoje instrukcje print.
To mylące zachowanie jest tak naprawdę spowodowane faktem, że tworzysz instancję przed zakończeniem inicjalizacji statycznej i że konstruktor, którego używasz, zależy od statycznej, która nie została jeszcze zainicjowana, i modyfikuje ją. To coś, czego powinieneś unikać w prawdziwym kodzie.