2017-02-15 42 views
1

Я записал эту мини-программу:Когда конструктор инициализирует?

A класс:

public class A 
{ 

    public A() 
    { 
     System.out.println(getS()); 
    } 

    public String getS() { return s;} 


} 

B класс:

public class B extends A 
{ 
    private String s = "hello2"; 

    public String getS() { return s;} 

} 

main:

public static void main(String[] args) 
{ 
    B b = new B(); 
} 

и напечатал:

null 

Почему это так?
Я знаю, что строка, напечатанная строка B, но почему она не инициализировалась раньше?

По this answer - переменная инициализируется перед конструктором ..

EDIT - я редактировал код так, несвязанный код не будет путать

+1

Поиск руководства по OO и конструктору по умолчанию. Тогда это было бы совершенно очевидно. – AxelH

+4

Возможный дубликат [Как работает конструктор при инициализации объекта?] (Http://stackoverflow.com/questions/23263369/how-does-the-constructor-work-while-initializing-an-object) –

+0

@dasblinkenlight Благодаря! Исправлено. –

ответ

3

Что происходит:

Вы создаете B экземпляр, это будет вызывать super() так конструктор A.

Здесь он будет печатать с использованием геттера getS(). Это будет использовать getter B, так как это тип this, но в этом получателе String еще не является instanciate, так как он все еще выполняет суперклассическую конструкцию, поэтому возвращает значение null.

Обратите внимание, что String s в A скрыт один в B

Порядок во время экземпляра является:

  • статический (из супер то класс)
  • супер класса декларация (инструкция then constructor)
  • инструкция блока
  • конструктор

As Seen с:

public class A{ 
    static{System.out.println("sA");} 
    {System.out.println("A1");} 

    public Main() { 
     System.out.println("new A"); 
    } 

    {System.out.println("A2");} 


    public static void main(String[] args) { 
     new A(); 
    } 
} 

class B extends Main { 
    static{System.out.println("sB");} 
    { System.out.println("B1"); } 

    public B() { 
     System.out.println("new B"); 
    } 

    { System.out.println("B2"); } 
} 

Выход:

sA 
sB 
A1 
A2 
new A 
B1 
B2 
new B 
+0

Исправьте меня, если я ошибаюсь - вы говорите, что строительство - это последнее, что произошло. Я знаю, что конструктор B вызывает конструктор A. Таким образом, инициализация выполняется до конструктора B, который находится перед конструктором A. Я ошибаюсь? –

+0

@DvirNaim Сначала создается суперкласс (с использованием 'super', если его нет), затем инициализация переменной экземпляра и блока оператора, затем выполняется конструктор. Вот почему 'супер' - это первый оператор, который должен присутствовать в конструкторе (и добавляется, если его нет). Прочтите пример и вывод, вы увидите каждый шаг здесь – AxelH

5

Вот что происходит: когда вы строите B, первым, что должен сделать его конструктор, является построение A. Это делается до того, как будет введено собственное поле Bs.

A создает свой собственный s, а затем звонит getS. Однако он не получает свой собственный getS, потому что B обеспечивает переопределение для него. Напомним, что B.s еще не был инициализирован. Вот почему вы печатаете null.

Последующая деятельность по итогам чтения: What's wrong with overridable method calls in constructors?

+0

http://stackoverflow.com/questions/26552799/which-run-first-default-values-for-instance-variables-or-super-constructors#answer-26553138 - Здесь говорится, что инициализация varibles перед конструктором. –

+1

@DvirNaim. Он говорит об инициализации переменных по умолчанию, а не настройке на то, что их инициализаторы указывают. То есть он говорит, что оба '' 'будут установлены в' null' до вызова конструкторов. – dasblinkenlight

+0

ох .. Я это неправильно понял .. Что за этим логично? Почему бы не начать сначала? –

1

печатает нуль, потому что у вас есть полиморфизм в Java. Вы переопределили метод getS(). Поэтому, когда вы вызываете его из A, вы пытаетесь вызвать getS() из класса B. Но вы еще не создали экземпляр класса B, потому что вам нужно сначала закончить класс A. Так что String в классе B еще не инициализирован, из-за этого вы получаете null.

 Смежные вопросы

  • Нет связанных вопросов^_^