Що static
модифікатор означає при застосуванні до оголошення змінної, це те, що змінна є змінною класу, а не змінною екземпляра. Іншими словами ... існує лише одна num1
змінна і лише одна num2
змінна.
(Убік: статична змінна схожа на глобальну змінну в деяких інших мовах, за винятком того, що її ім’я не видно скрізь. Навіть якщо вона оголошена як public static
, некваліфіковане ім’я видно лише в тому випадку, якщо вона оголошена в поточному класі або надкласовій або якщо він імпортований за допомогою статичного імпорту. Це відмінність. Справжній глобальний світ видно без будь-якої кваліфікації.)
Тому , коли ви дивитеся obj.num1
і obj.num2
ви насправді маючи на увазі на статичні змінні, речові позначення A.num1
і A.num2
. І також, коли конструктор збільшується num1
і num2
, він збільшує ті самі змінні (відповідно).
Заплутана зморшка у вашому прикладі полягає в ініціалізації класу. Клас ініціалізується спочатку за замовчуванням ініціалізацією всіх статичних змінних, а потім виконанням оголошених статичних ініціалізаторів (та статичних блоків ініціалізаторів) у тому порядку, як вони відображаються в класі. У цьому випадку у вас є таке:
static A obj = new A();
static int num1;
static int num2=0;
Буває так:
Статика починається зі своїх стандартних початкових значень; A.obj
є null
і A.num1
/ A.num2
є нулем.
Перше оголошення ( A.obj
) створює екземпляр A()
і конструктор для A
збільшення A.num1
та A.num2
. Коли декларація завершується A.num1
і A.num2
є обома 1
, і A.obj
посилається на щойно побудований A
екземпляр.
У другій декларації ( A.num1
) немає ініціалізатора, тому A.num1
не змінюється.
Третя заява ( A.num2
) має ініціалізатор, який присвоює нуль A.num2
.
Таким чином, наприкінці класу ініціалізація A.num1
є 1
і A.num2
є 0
... і ось що показують ваші друковані заяви.
Ця заплутана поведінка насправді зводиться до того, що ви створюєте екземпляр до завершення статичної ініціалізації, і що конструктор, який ви використовуєте, залежить від та змінює статику, яку ще слід ініціалізувати. Це те, чого вам слід уникати робити в реальному коді.