Что static
означает модификатор , когда применяется к декларации переменной является то , что переменная является переменной класса , а не переменная экземпляра. Другими словами ... есть только одна num1
переменная и только одна num2
переменная.
(Кроме того: статическая переменная похожа на глобальную переменную в некоторых других языках, за исключением того, что ее имя не отображается везде. Даже если оно объявлено как a 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
... и это то, что показывают ваши операторы печати.
Это сбивающее с толку поведение на самом деле связано с тем, что вы создаете экземпляр до завершения статической инициализации и что используемый вами конструктор зависит от статического объекта, который еще не инициализирован, и изменяет его. Этого вам следует избегать в реальном коде.