Порядок конструктора Java - PullRequest
       1

Порядок конструктора Java

0 голосов
/ 07 октября 2011

Эта java-программа проста и полна комментариев, так что вы можете быстро ее понять. Однако, почему в конструкте персонала [1] программа сначала идет к утверждению:

this("Employee #" + nextId, s);

, затем идете кблок инициализации объекта, а затем вернитесь к утверждению, как путаница. Почему бы сначала не использовать блок инициализации объекта

import java.util.*;

public class ConstructorTest
{
   public static void main(String[] args)
   {
      // fill the staff array with three Employee objects
      Employee[] staff = new Employee[3];

      staff[0] = new Employee("Harry", 40000);
      staff[1] = new Employee(60000);
      staff[2] = new Employee();

      // print out information about all Employee objects
      for (Employee e : staff)
         System.out.println("name=" + e.getName()
            + ",id=" + e.getId()
            + ",salary=" + e.getSalary());
   }
}

class Employee
{
   // three overloaded constructors
   public Employee(String n, double s)
   {
      name = n;
      salary = s;
   }

   public Employee(double s)
   {
      // calls the Employee(String, double) constructor
      this("Employee #" + nextId, s);
   }

   // the default constructor
   public Employee()
   {
      // name initialized to ""--see below
      // salary not explicitly set--initialized to 0
      // id initialized in initialization block
   }

   public String getName()
   {
      return name;
   }

   public double getSalary()
   {
      return salary;
   }

   public int getId()
   {
      return id;
   }

   private static int nextId;

   private int id;
   private String name = ""; // instance field initialization
   private double salary;

   // static initialization block
   static
   {
      Random generator = new Random();
      // set nextId to a random number between 0 and 9999
      nextId = generator.nextInt(10000);
   }

   // object initialization block
   {
      id = nextId;
      nextId++;
   }
}

Ответы [ 4 ]

4 голосов
/ 07 октября 2011

Поскольку this("Employee #" + nextId, s); включает в себя неявный вызов конструктора суперкласса, который, конечно, должен быть выполнен до блока инициализатора подкласса.

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

1 голос
/ 07 октября 2011

Это соответствует порядку, указанному в разделе 8.8.7.1 JLS :

(последние две пули)

Позвольте C быть экземпляром класса, пусть S будет прямым суперклассом C, и позвольте мне быть создаваемым экземпляром. Оценка явного вызова конструктора выполняется следующим образом:

  • Во-первых, если оператор вызова конструктора является вызовом конструктора суперкласса, (Отрезано, потому что это не в нашем случае)
  • Далее вызывается конструктор.
  • Наконец, если оператор вызова конструктора является вызовом конструктора суперкласса, а оператор вызова конструктора завершается нормально, то выполняются все инициализаторы переменных экземпляра C и все инициализаторы экземпляра C. (Snip) Альтернативный вызов конструктора не выполняет это дополнительное неявное действие.

Таким образом, инициализатор экземпляра выполняется сразу после вызова суперконструктора , который (неявно) из public Employee(String n, double s). Это должно произойти до того, как будет выполнено тело этого двухпараметрического конструктора.

0 голосов
/ 07 октября 2011

Компилятор Java должен гарантировать, что код в блоке инициализации объекта вызывается из каждого конструктора.Для большинства конструкторов это делается путем вставки кода в конструктор сразу после неявного или явного вызова super().Однако для компиляторов, которые начинаются с this(), в первую очередь означает неявный вызов super() - другой конструктор обрабатывает это.Во-вторых, в таком конструкторе блок инициализатора объекта вообще не может быть вставлен, так как код будет выбран при вызове второго конструктора.Поэтому this() вызов - это самое первое, что происходит.

0 голосов
/ 07 октября 2011

Не уверен, что на самом деле вопрос, это немного сбивает с толку.Порядок инициализации (статический, объект, конструктор) предопределен и не имеет никакого отношения к тому, в каком порядке они появляются в коде.Что касается общего стиля, я обычно не рекомендую использовать блоки инициализации объекта.Это очень распространенный источник ошибок, он усложняет обработку исключений и затрудняет отладку.Кроме того, это не очень распространенный шаблон, поэтому разработчики, как правило, упускают его при анализе ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...