Наследование в Java

Добрый день!
Казалось бы простая задачка, но ввела меня в тупик.
Есть классы:

abstract class Animal {
	static {
		System.out.println("Inside Animal abstract class");
	}
}
public class Cat extends Animal {
	static{
		System.out.println("Inside Cat class");
	}
}
public class Dog extends Animal{
	static{
		System.out.println("Inside Dog class");
	}
}
public class Main{
	public static void main(String[] args){
		System.out.println("Inside Main class");
		Animal cat = new Cat();
		Animal dog = new Dog();
	}
}
На выходе ожидал получить:
Inside Main class
Inside abstract class Animal
Inside Bird class
Inside abstract class Animal
Inside Dog class

...но получаю
Inside Main class
Inside abstract class Animal
Inside Bird class
Inside Dog class

Почему так?
👍НравитсяПонравилось0
В избранноеВ избранном0
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

А че статика переинициализируетсо при каждом создании объекта?

нет, она загрузится всего 1 раз при первой загрузке файла

Static init blocks run once, when the class is first loaded

Это был намек ТСу, где у него ошибка.

Кстати Thinking in Java содержит похожий пример с вероятностью в 100 %. Читать книжки — уже не круто?

Напротив!) В данный момент читаю Хорстмана, но как-то этот момент прошел мимо глаз.

www.quizful.net — русскоязычный ресурс по тестам, там классные вопросы по Java, много нюансов можно узнать

Первое, бёрда тут вообще нету)
Второе, при наследовании сначала вызывается конструктор "отца"(тоже самое происходит с инициализацией статических блоков), что и имеем тут. При создании объекта cat сначала вызывается блок инициализации родителя (animal), так как он объявлен как статик инициализируется в этом классе всего 1 раз. Поэтому и имеем
inside abstract class Animal
Inside Cat class

Inside Dog class

По поводу первого, не заметил) Вывод выложил из дебаггера.
По поводу второго, если я правильно понял, то ход действий такой:
1) Вызывается и инициализируется конструктор Animal.
2) Вызывается и инициализируется конструктор Cat.
3) Так как Animal уже инициализирован, то static{...} уже не срабатывает и создается конструктор Dog.

Я все правильно понял?

Да, все верно, но не совсем, это не конструктор,а блок инициализации.

Ага, тогда все ясно, спасибо!

Всегда пожалуйста, если что задавайте еще вопросы, как по мне, на этом форуме, именно программерских вопросов и не хватает.

Почитайте [2005]Oracle Press — Sun Certified Java Programmer Study Guide.

Стр. 226:
Remember these rules:
— Init blocks execute in the order they appear.
— Static init blocks run once, when the class is first loaded.
— Instance init blocks run every time a class instance is created.
— Instance init blocks run after the constructor’s call to super().

Спасибо, она как раз стояла следующей в моем списке к прочтению после Хорстмана.

Подписаться на комментарии