Вызов метода из конструктора

Извините за любые незначительные синтаксические ошибки или что-то еще, я испытываю это с помощью модуля Jitsi и не очень хорошо разбираюсь в Java, хочу подтвердить, что происходит, и почему и как его следует исправлять.

public abstract class A { public A() { this.load(); } protected void load() { } } public class B extends A { private String testString = null; public B() { super(); } @Override protected void load() { testString = "test"; } } 

Приложение делает это при создании экземпляра classа B с использованием classа нагрузки по методу name:

  • Вызывает переопределенную нагрузку () в classе B
  • Инициализирует переменные (вызывает «private string testString = null» в соответствии с отладчиком), обнуляя их.

Является ли это ожидаемым поведением Java? Что может быть причиной этого? Это приложение Java 1.6, работающее на 1,7 JDK.

Является ли это ожидаемым поведением Java?

Да.

Что может быть причиной этого?

Вызов неконфигурированного переопределенного метода в конструкторе внеclassного суперclassа.

Давайте посмотрим, что происходит шаг за шагом:

  • Вы создаете экземпляр B
  • B() вызывает super class constructor – A() , чтобы инициализировать члены суперclassа.
  • A() теперь вызывает не конечный метод, который переопределяется в classе B , как часть инициализации.
  • Поскольку экземпляр в контексте относится к classу B , метод load() вызывается из classа B
  • load() инициализирует поле экземпляра classа BtestString .
  • Конструктор суперclassа завершает работу и возвращает (предположив, что цепочка конструктора до classа Object завершена)
  • Конструктор B() начинает выполнение, инициализируя его собственный член.
  • Теперь, в рамках процесса инициализации, B перезаписывает предыдущее записанное значение в testString и повторно инициализирует его до null .

Мораль: никогда не вызывать неконкурентный публичный метод не конечного classа в его конструкторе.

Это типичная проблема-шаблон с инициализацией в конструкции и часто может быть найдена в коде инфраструктуры и самодельных DAO.

Назначение «null» не требуется и может быть удалено.

Если этого недостаточно, как быстрый патч, то: Переместите все post-construction init в отдельный метод и оберните все это в псевдо-конструктор «статический метод».

И если вы делаете вещи DAO, очень приятно различать «load» и «create», поскольку это совершенно разные экземпляры. Определите отдельные методы «статического конструктора» и, возможно, отделите их внутренние.

 abstract public class A { protected void initAfterCreate() {} } public class B { @Override protected void initAfterCreate() { this.testString = "test"; } // static constructors; // -- static public B createB() { B result = new B(); result.initAfterCreate(); } } 

Демонстрация нагрузки / создания разделения для DAO:

 public class Order { protected int id; protected boolean dbExists; static public load (int id) { Order result = new Order( id, true); // populate from SQL query.. return result; } static public create() { // allocate a key. int id = KeyAlloc.allocate( "Order"); Order result = new Order( id, false); } // internal constructor; not for external access. // protected Order (int id, boolean dbExists) { this.id = id; this.dbExists = dbExists; } } 
  • Может ли конструктор в Java быть приватным?
  • Как вызвать конструктор базового classа?
  • DataContractSerializer не вызывает мой конструктор?
  • Можно ли вызвать конструктор из другого конструктора (сделать цепочку конструктора) в C ++?
  • механизм вызова конструктора
  • Вызовите asynchronous метод в конструкторе?
  • Почему нет вызова конструктору?
  • Может ли абстрактный class иметь конструктор?
  • Создание объектов: конструкторы или статические заводские методы
  • Не может ли тип C ++ POD иметь какой-либо конструктор?
  • избегая скуки факультативных параметров
  • Interesting Posts

    Прокладка и упаковка структуры

    Как найти факториал?

    Bash: чтение ввода внутри, в то время как цикл чтения не работает

    Преобразование даты в MySQL из поля строки

    Что делает InputStream.available () в Java?

    Как определить, является ли десятичное / двойное целое?

    Как вручную создать cookie проверки подлинности вместо метода по умолчанию?

    Intellij – Невозможно использовать новые classы Java 8 – Ошибка: «Использование API, зарегистрированное как @since 1.6+ ..»

    Как я могу получить WPF EventTrigger в триггере View, если он требует диктует базовую модель Viewmodel?

    Как увеличить размер кучи приложения в Eclipse?

    Что вызывает измельчение жесткого диска?

    Запуск jquery с запросами css media

    Может ли Firefox иметь две Windows или вкладки, открытые бок о бок, каждый для другого профиля (один для работы, один для личного использования)? IE 8 может, но не может запомнить профили

    Как сделать HTTP-запрос HTTP POST

    Несколько условий соединения с помощью оператора $ lookup

    Давайте будем гением компьютера.