class A {
int xyz = new B().show(); // prints c=0 and z=null
int c = -319;
B z = new B();
int lmn = z.show(); // prints c=-319
class B {
int show() {
System.out.println("c=" + c);
System.out.println("z=" + z);
return -555;
}
}
}
class C {
public static void main(String args[]) {
A p = new A();
}
}
Почему я получаю c=0
изначально, а затем c=-319
позже. Точно так же, почему z null
первоначально и после него не является null
. Что происходит в коде?
Вы должны знать, что new
оператор отвечает за создание пустого экземпляра класса (экземпляр с полями, которые будут иметь значения по умолчанию: numeric: 0
; boolean: false
, char: '\0'
, reference: null
). Код конструктора вызывается после того, как new
завершит свое задание и отвечает за правильное состояние для такого пустого объекта.
Теперь инициализация полей происходит в конструкторе, поэтому ваш код
class A {
int xyz = new B().show(); // prints c=0 and z=null
int c = -319;
B z = new B();
int lmn = z.show(); // prints c=-319
class B {
int show() {
System.out.println("c=" + c);
System.out.println("z=" + z);
return -555;
}
}
}
это то же самое, что (обратите внимание на значения по умолчанию)
class A {
int xyz = 0; //default values
int c = 0; //
B z = null; //
int lmn = 0; //
A(){
xyz = new B().show();
c = -319;
z = new B();
lmn = z.show();
}
class B {
int show() {
System.out.println("c=" + c);
System.out.println("z=" + z);
return -555;
}
}
}
Также
xyz = new B().show();
такое же, как
xyz = this.new B().show();
поэтому созданный экземпляр B
будет иметь доступ к экземпляру A
который инициализируется в текущем конструкторе A
BUT код, который инициализировал b
и z
int c = -319;
B z = new B();
происходит после вашего первого метода show()
(который использует b
и z
), что означает, что будут отображаться их значения по умолчанию.
Эта проблема не существует в случае второго show()
lmn = z.show();
потому что теперь b
и z
инициализируются.
Когда вы создаете Object A в классе C как
A p = new A();
Конструкция по умолчанию получает класс и объект создается с переменными-членами класса со значениями по умолчанию. В этих точках значения переменных класса следующие:
См. Снимок экрана, чтобы увидеть переменные состояния
Когда он достигает инструкции ниже для оценки значений xyz:
int xyz = new B().show()
он печатает значение c и z, инициализация которого еще не выполнена, поэтому мы получим значения по умолчанию этих переменных как 0 и NULL соответственно.
Когда 2-й раз, программа вызывает метод show() класса B. Все инициализации переменных были выполнены, потому что ниже операторы выполняются до момента, когда мы дойдем до z.show()
int c = -319;
b z= new (B); // call the default constructor of B to create object
См. Ниже снимок экрана, чтобы увидеть состояния переменных.
поэтому он печатает значение C как -319 и z как шестнадцатеричные значения объекта. (не ноль)
Класс создается с достаточной памятью, чтобы содержать все его поля.
Когда вы выполните:
A p = new A();
Это выделяет память для A и ее полей (xyz, c, z и lmn). Все они распределены в памяти со значениями по умолчанию (c is int so 0, z - объект, поэтому null [address is 0x00]).
Когда вы запускаете:
int xyz = new B().show(); // prints c=0 and z=null
Вы создаете новый экземпляр B. Когда этот экземпляр ссылается на c и z, он печатает свои значения. В настоящее время они являются значениями по умолчанию. Во всех смыслах и целях перспектива show() заключается в том, что все поля, на которые он ссылается, были определены/объявлены или, по крайней мере, выделены.
Затем, когда вы выполняете:
B z = new B();
int lmn = z.show(); // prints c=-319
И c, и z получили новые значения. Но во всех точках вашего кода они были выделены и имели некоторое значение (первый по умолчанию).
В line 2
Вы вызываете int xyz = new B().show();//prints c=0 and z=null
int xyz = new B().show();//prints c=0 and z=null
в начале.
Какие звонки
class B {
int show() {
System.out.println("c=" + c);
System.out.println("z=" + z);
return -555;
}
}
в вышеприведенном коде вы получаете доступ к переменным c
и Z
которые являются переменными-членами класса и поскольку не инициализированы, но им были присвоены значения по умолчанию.
boolean => false
char => \u0000
int,short,byte / long => 0 / 0L
float /double => 0.0f / 0.0d
any reference type => null
В вашем случае " ìnt
назначено на 0
и ссылка на объект присвоена null
Переместите код line 2
в line 4
и он должен печатать, так как переменная инициализируется.
A
и вставите логику в методa()
, должно быть очевидно, что происходит.