2012-06-18 2 views
2

Странно, но я не могу найти дубликат для этого вопроса. У меня есть суперкласс с методом overrideMe() и подкласс, который переопределяет его. Является ли окончательное поле действительно инициализированным до вызова конструктора подкласса? Как я могу видеть на выходе, это так.Инициализация конечного поля в подклассе

Вот результат: Superclass CONSTR значение ул: SomeValue Подкласс CONSTR ул значение: SomeValue

Не могли бы вы объяснить мне это? Я думал, что переменные экземпляра инициализируются внутри вызова конструктора, но не раньше него.

Вот код:

public class Test { 
    public Test() { 
    System.out.println("Superclass constr"); 
    overrideMe(); 
    } 

    public void overrideMe() { 
    } 
} 

class Ext extends Test { 
    private final String str = "someValue"; 

    public Ext() { 
    System.out.println("Subclass constr"); 
    } 

    @Override 
    public void overrideMe() { 
    System.out.println("str value: " + str); 
    } 

    public static void main(String[] args) { 
    Ext test = new Ext(); 
    test.overrideMe(); 
    } 
} 

EDIT: если я declasre ул поле неконечное, подкласс вызова его в конструкторе возвращает нуль, как я ожидал.

+0

Каждый конструктор вызывает 'super' (или' this', который вызывает 'super'), чтобы первый класс сначала инициализировался. (За исключением 'java.lang.Object', который не имеет супер) –

ответ

2

Да, поля инициализируются перед вызовом конструктора, и это начинается с верхнего класса перед перегрузкой.

Вот общее представление: http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ306_014.htm

+2

[JLS 7] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5) для большей ясности –

+0

К сожалению, это был действительно глупый вопрос :) Единственное, что я до сих пор не могу получить, - это то, почему окончательное поле сначала не инициализируется нулевым. – iozee

+0

@iozee последнее поле никогда не меняется. После этого он не может быть инициализирован с нулевым значением и значением изменения. –

1

Конечное поле с инициализатором будет заменены константной строкой компилятора, поэтому казалось, что поле инициализируется еще до того, как супер конструктора вернулся.

Если конечное поле пустое, что означает, что оно включено в конструктор дочернего класса, то, конечно, суперконструктор увидит нуль.

Если поле не является ни окончательным, ни статическим, а предусмотрено инициализатор, он будет включен после супер-конструктора и перед дочерним конструктором.

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