Теперь, на основе предыдущих знаний еще чуть расширим свое сознание о том как и в какой очередности происходит создание объектов в памяти и инициализация полей значениями. Рассмотрим простой пример:
Вывод этой программы уже должен быть вам понятен:
Смысл этой программы показать, что оператор new создает объект в памяти сразу после своего вызова и инициализирует все поля значениями по умолчанию.
После этого, последовательно, вызываются все инициализационные блоки и инициализаторы полей суперклассов (если они есть), а затем происходит вызов конструкторов суперклассов.
Как видно из вывода программы при создании объекта Sub, сперва были вызваны инициализационные блоки и инициализатор поля суперкласса. Затем был запущен конструктор суперкласса, но поскольку метод display() переопределен в подклассе Sub, то он нам вывел значение поля set объекта данного подкласса. Данный вывод подсвечен желтым в скрине. Далее происходит вывод значения поля set суперкласса. Затем отрабатывают инициализационные блоки подкласса и инициализация поля set подкласса. Далее отрабатывает конструктор подкласса в котором выводится значение поля set подкласса.
>затем происходит инициализация полей значениями которые указаны при их определении
ОтветитьУдалитьт.е. String set = "MySuperString" при создании экземпляра Sub не участвует?
Конечно участвует. Я чуток переделаю этот пример чтобы стало более понятно.
Удалитьclass Test1{
ОтветитьУдалитьString a = "test1";
Test1(){
System.out.println(a);
}
}
class Test2 extends Test1 {
String a = "test2";
Test2() {
System.out.println(a);
}
}
public class Main {
public static void main(String[] args) {
// write your code here
new Test2();
}
}
Вот такой код у меня выдал:
test1
test2
Прочитав эту заметку, я ожидал null вместо test1. Где я ошибаюсь?
У вас нет замещенного метода как у меня.
УдалитьПоясните, пожалуйста, откуда Sub set = null получается.
УдалитьОбъяснение выделено желтым в тексте статьи.
УдалитьСпасибо, стало гораздо понятнее. Интересная ситуация получается. То есть если конструктор родительского класса вызывает метод, переопределенный в потомке, можно наступить на нефиговые грабли :) Как с такой ситуацией бороться? Сделать метод, вызываемый конструктором, методом класса?
УдалитьИнтересно, вы читали предыдущую статью? http://pr0java.blogspot.ru/2015/07/blog-post_62.html
УдалитьДа, сорри, прочитал уже после того как оставил комментарий. Не сразу понял, что у вас в блоге последовательное изложение, а не набор standalone заметок :)
Удалить