Почему я получаю два разных вывода в коде Java

1
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. Что происходит в коде?

  • 4
    Инициализация происходит по порядку сверху вниз. Если вы избавитесь от класса A и вставите логику в метод a() , должно быть очевидно, что происходит.
  • 0
    не должен ли этот оператор int xyz = new B (). show () выдавать ошибку «Недопустимая прямая ссылка», поскольку show () использует c, который еще не выделил память?
Показать ещё 3 комментария
Теги:
object
oop
inner-classes

4 ответа

3
Лучший ответ

Вы должны знать, что 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 инициализируются.

  • 0
    спасибо, что бросил это. Делает это так ясно. Ура!
  • 0
    @ user3678484 Добро пожаловать :) Кстати, я добавил некоторую информацию, которая, возможно, сделает ее еще яснее.
0

Когда вы создаете Object A в классе C как

A p = new A();

Конструкция по умолчанию получает класс и объект создается с переменными-членами класса со значениями по умолчанию. В этих точках значения переменных класса следующие:

  • xyz = 0 (потому что это тип int)
  • c = 0 (потому что это также int)
  • z = null (потому что это ссылка)
  • lmn = 0 (потому что это если тип int)

См. Снимок экрана, чтобы увидеть переменные состояния

Изображение 174551

Когда он достигает инструкции ниже для оценки значений 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

См. Ниже снимок экрана, чтобы увидеть состояния переменных.

Изображение 174551

поэтому он печатает значение C как -319 и z как шестнадцатеричные значения объекта. (не ноль)

0

Класс создается с достаточной памятью, чтобы содержать все его поля.

Когда вы выполните:

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 получили новые значения. Но во всех точках вашего кода они были выделены и имели некоторое значение (первый по умолчанию).

0

В 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 и он должен печатать, так как переменная инициализируется.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню