2014-02-17 5 views
0
class Parent 
{ 
    public static String sName = "Parent"; 
    static 
    { 
    System.out.println("Parents static block called");  
    sName = "Parent"; 
    } 
} 

class Child extends Parent 
{ 
    public static String sName1; 
    static 
    { 
    System.out.println("Childs static block called");  
    sName = "Child"; 
    sName1 = "Child"; 
    } 
} 

public class Inheritance 
{ 
    public static void main(String []args) 
    {  
    System.out.println(Child.sName); 
    System.out.println(Parent.sName); 
    } 
} 

В приведенном выше фрагменте кода у меня есть «Parent» класс и «Child» класс, который расширяет Parent. Я понимаю, что статические переменные распределяются между родителями и всеми его подклассами. Когда я запускаю выше программы выходСтатические переменные в Java

Parents static block called 
Parent 
Parent 

Интересно, почему статический блок по правам ребенка не выполняется даже после выполнения «System.out.println(Child.sName);». Я не уверен, почему загружается только родительский класс, а не класс Childs. Теперь, когда я изменяю функцию main(), как показано ниже, загружается класс Child.

public static void main(String []args) 
{  
    System.out.println(Child.sName); 
    System.out.println(Parent.sName); 
    System.out.println(Child.sName1); //sName is declared in Child class. 
    System.out.println(Parent.sName); 
} 

Выходные данные теперь показаны ниже и как ожидается. Теперь класс Child должен загрузиться, поскольку мы делаем ссылку на статическую переменную sName1, которая объявлена ​​в классе Child.

Parents static block called 
Parent 
Parent 
Childs static block called 
Child 
Child 

Статическая переменная «sName» теперь «Child» в качестве значения. Мой вопрос здесь в том, почему класс Child не загружается даже после того, как он сделал ссылку в первой строке в главной функции перед ее модификацией?

Просьба сообщить.

+2

Статические переменные не наследуются. Когда Child делает 'sName = ..', вы фактически устанавливаете статическую переменную' sName', определенную в Parent (она эквивалентна 'Child.sName = ..', что эквивалентно' Parent.sName = ..'). Таким образом, это не имеет никакого отношения к наследованию, а скорее порядок (и причина) выполнения статического блока. – user2864740

+0

Только что изменил заголовок сообщения. Да, я понимаю, что статические переменные не наследуются. Но когда вы говорите, что имя Child.sName не должно быть вызвано статическим блоком Childs? – Rahul

+0

@Rahul Просто проверьте скомпилированный байт-код с помощью команды 'javap', и вы узнаете, что происходит. –

ответ

3

От JLS

Класса или типа интерфейса Т будет инициализирован непосредственно перед первого вхождения любого одного из следующих действий:

  • T - это класс и создается экземпляр T.
  • T - класс, и статический метод, объявленный T, вызывается.
  • Статическое поле, объявленное T, назначается.
  • Статическое поле, объявленное T, используется, и поле не является постоянной переменной (§4.12.4).
  • T - класс верхнего уровня, и выполняется инструкция assert (§14.10), лексически вложенная в T.

В первом случае (первый набор печатного staments), у вас есть доступ только лишь переменная sName, и это принадлежит к классу Parent, поэтому дочерний класс не был инициализирован.

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

Это не имеет значения, даже если вы получили доступ к Child.sName, он фактически ссылается на Parent.sName, поэтому он не загрузит класс Child.

+0

Я попробовал запустить код выше, но вместо использования System.out.println (Child.sName); в первом заявлении я назвал System.out.println (Child.sName1); но все же был вызван статический блок родителя. Как это произошло, поскольку переменная sName1 принадлежит дочернему классу, а не родительскому классу – anathema

-1
class Parent 
{ 
    public static String sName = "Parent"; // here you defining **sName** as static 
    static 
    { 
    System.out.println("Parents static block called");  
    sName = "Parent"; 
    } 
} 


class Child extends Parent 
{ 
    public static String sName1; // here you defining **sName1** as static 
    static 
    { 
    System.out.println("Childs static block called");  
    sName = "Child"; 
    sName1 = "Child"; 
    } 
} 

поэтому, когда вы звоните System.out.println(Child.sName); зЫате это объявить статический в class parent. программа получит значение, сохраненное в sName (i.e sName = "Parent";, определенное в статическом блоке внутри класса parent). так что вы делаете результат Родитель.

и аналогичный для другого случая

System.out.println(Child.sName); 
    System.out.println(Parent.sName); 
    System.out.println(Child.sName1); //sName is declared in Child class. 
    System.out.println(Parent.sName); 
+0

, почему downvote ???? – Ashish

+0

Я действительно не понимаю, почему люди сбиты с толку! Это место для обмена и изучения вещей. Конечно, я прошел через пару сообщений, прежде чем публиковать этот. Я не получил то, что искал, и поэтому я отправил! – Rahul

+0

нет проблем с пустым голосованием, но почему в моем ответе не так – Ashish

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