Подтвердить что ты не робот

Почему выполняется статический код подкласса?

Я написал следующий код и создал объект для суперкласса.

class SuperClass{
    static int a=2;
    static int b(){
        return 2;
    }
    int c(){
        return 2;
    }

    SuperClass(){
        System.out.println("Super");
    }
    static {
        System.out.println("super");
    }
}

public class Sub extends SuperClass{
    Sub(){
    System.out.println("Sub");
    }
    static {
        System.out.println("sub");
    } 
    static int b(){
        return 3;
    }
    int c(){
        return 3;
    }
    public static void main(String ax[]){
        SuperClass f =new SuperClass();
        System.out.println(f.c());
        System.out.print(SuperClass.b());
    }   
}

Когда я проверил вывод, это выглядит следующим образом:

super
sub
Super
2
2

Я знаю, что статический блок выполняется только тогда, когда объект класса инициализирован или делается статическая ссылка. Но здесь я не сделал ни одного из них для Sub-класса. то почему я вижу "суб", то есть подкласс класса "статический вывод блока"?

4b9b3361

Ответ 1

Я знаю, что статический блок выполняется только тогда, когда объект класса инициализирован или делается статическая ссылка. Но здесь я не сделал ни одного из них для класса Sub.

Ваш код не работает, но для этого main для запуска нужно загружать Sub. Поэтому запускается статический инициализатор для него.

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

java Sub

Инструмент java должен загрузить Sub, чтобы вызвать Sub.main. Это статическая ссылка (доступ, действительно), вызывающий запуск статического инициализатора. (Если вы запустили его в среде IDE, среда IDE выполнит часть инструмента java, но результат будет таким же.)

Итак, вот что произошло:

  • java запускает загрузку Sub

  • JVM должен загрузить SuperClass, чтобы загрузить Sub

  • Итак, мы видим, что их статические инициализаторы выполняются в порядке (SuperClass, затем Sub):

    super
    sub
    
  • java вызовы инструментов main

  • Код в main вызывает new SuperClass:

    Super
    
  • Код в main вызывает f.c()

    2
    
  • Код в main вызывает SuperClass.b:

    2
    

Как Holger указывает, это описывается спецификацией JVM в §5.5 - Инициализация и связанный с ним §5.2 - Запуск виртуальной машины Java:

Инициализация класса или интерфейса состоит в выполнении его метода инициализации класса или интерфейса (§2.9).

Класс или интерфейс C может быть инициализирован только в результате:

  • ...

  • Если C - класс, инициализация одного из его подклассов.

  • Если C является классом, его обозначение как начальный класс при запуске виртуальной машины Java (§5.2).

Эта вторая точка пули покрывает SuperClass, а последняя точка пули охватывает Sub.

Ответ 2

Поскольку ваш метод main() является членом Sub, этот класс необходимо загрузить для запуска вашей программы.

Ответ 3

При вызове main все статические инициализаторы вызывается сначала в суперклассе, затем подклассе.

Это объясняет результат, который вы наблюдаете.

Ответ 4

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

боковые заметки:

  • другой краевой регистр вызывает Class.forName(className) для загрузки класса.
  • вы также можете заметить, что базовый класс загружается перед подклассом.