2013-04-28 3 views
-1

Почему переменные класса инициализируются до того, как конструктор вызывается, если рассматриваемый класс не расширяет какой-либо другой класс, но конструктор сначала вызван, а инициализация переменных класса выполняется, если рассматриваемый класс расширяет некоторые другие классы!Порядок инициализации в классе

например. допустим, у меня есть класс

public class Windows { 
    public Windows() { 
     System.out.println("in window"); 
    } 
} 

и у меня есть один базовый класс.

public class BaseClass { 
    public BaseClass() { 
     System.out.println("in base"); 
    } 
} 

и, наконец, у меня есть еще один класс.

public class ChildClass extends BaseClass { 

Windows w = new Windows(); 

public ChildClass() { 
    System.out.println("in subclass"); 

} 

public static void main(String[] args) { 
    System.out.println(new ChildClass()); 
} 
} 

приведет к

в базе в окне в подклассе

, который предполагает, что конструктор базового класса получил под названием, которое означает ChildClass конструктор получил колл, но после того, как BaseClass конструктор закончил , почему поле было инициализировано? то есть она не должна быть чем-то вроде

в базе в подклассе в окне

Это будет объяснить что-то!

Опять же, если я сделать

public class ChildClass { 

Windows w = new Windows(); 

public ChildClass() { 
    System.out.println("in subclass"); 

} 

public static void main(String[] args) { 
    System.out.println(new ChildClass()); 
} 
} 

я получу

в окне в подклассе

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

Некоторые объяснения состоят в том, что JVM сначала сначала инициализирует материал базового слоя, затем переходит в поля текущего класса и, наконец, конструктор. Это правда?

Некоторые объяснения будут большими !!

+1

Вы могли бы хотеть проверить это: http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2 –

+2

Если только там был какая-то спецификация, которая подробно описывает язык Java, например, спецификацию Java Language Specification. –

+0

Терминология пожалуйста. Здесь нет «переменных класса». Они были бы статичными. Существуют * переменные экземпляра *. – EJP

ответ

4

Ваш лучший друг относительно Java - это Java Language Specification. Что касается вашего вопроса, то вы можете найти ответ here:

Непосредственно перед ссылкой на вновь созданный объект возвращается как результата, указанный конструктор обрабатывается для инициализации нового объекта с помощью следующей процедуры:

  1. Назначить аргументы для конструктора новым созданным переменным параметра для этого вызова конструктора.
  2. Если этот конструктор начинается с явного вызова конструктора (§8.8.7.1) другого конструктора в том же классе (используя это), то оценивает аргументы и обрабатывает вызов конструктора рекурсивно, используя эти пять шагов. Если вызов конструктора завершается внезапно, то эта процедура завершается внезапно по той же причине; в противном случае перейдите к шагу 5.
  3. Этот конструктор не начинается с явного вызова конструктора другого конструктора в том же классе (используя это). Если этот конструктор предназначен для класса, отличного от Object, то этот конструктор начнет с явного или неявного вызова конструктора суперкласса (используя супер). Вычислите аргументы и обрабатываете вызов конструктора суперкласса рекурсивно, используя эти те же пять шагов. Если вызов конструктора завершается внезапно, , то эта процедура завершается внезапно по той же причине. В противном случае, перейдите к шагу 4.
  4. выполнять экземпляр инициализаторы и экземпляр инициализаторы переменных для данного класса, присвоение значения переменной экземпляра Инициализаторы к соответствующим переменным экземпляра, в слева направо порядок, в котором они появляются текст в исходном коде для класса. Если выполнение любого из этих инициализаторов приводит к исключению , то никаких последующих инициализаторов не обрабатываются, и эта процедура завершается внезапно с тем же исключением. В противном случае, перейдите к шагу 5.
  5. Выполнение остальной части тела этого конструктора. Если это выполнение завершается внезапно, то эта процедура завершается внезапно по той же причине. В противном случае эта процедура завершится нормально.
+0

Спасибо, именно то, что я искал! – magiclko

+0

Однако вы выбрали странное место для просмотра. Вам следует начать с JLS. – EJP

+0

Я немного смущен ... JLS? = Спецификация языка Java? –

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