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

Инициализировать переменные-члены в начале определения класса или в конструкторе?

В чем разница между определением и инициализацией переменных-членов в начале определения класса и сначала определением переменных-членов и инициализацией переменных-членов в конструкторе?

Скажем, например:

public class Test {
   private int foo = 123;
   private boolean flag = false;

   public void fooMethod() {...}
}

Versus:

public class Test {
   private int foo;
   private boolean flag;

   public Test() {
      foo = 123;
      flag = false;
   }

   public void fooMethod() {...} 
}

Спасибо заранее.

4b9b3361

Ответ 1

В вашем примере единственная разница заключается в том, когда они инициализируются. Согласно JLS, переменные экземпляра инициализируются до вызова конструктора. Это может стать интересным, когда у вас есть суперклассы для рассмотрения, поскольку порядок инициализации не всегда так очевиден. При этом помните, что переменные экземпляра "супер" все еще будут инициализированы, когда не будет вызван явный суперструктор.

Ответ 2

Разница - это порядок, в котором они инициализированы/установлены.

Ваши переменные-члены класса будут объявлены/установлены до вызова вашего конструктора. Мои личные предпочтения - установить их в конструкторе.

Ответ 3

Инициализация внутри класса позволяет избежать написания тривиального конструктора.

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

В противном случае нет разницы.

Ответ 4

Обычно конструктор принимает аргументы и присваивает эти аргументы полям класса.

public Test(int foo, boolean flag)
{
   this.foo = foo;
   this.flag = flag;
}

Ответ 5

Инициализация, когда они объявлены, происходит первой (и гарантирует, что они всегда что-то инициализируют). Это обычно, где вы положили бы значение по умолчанию. Далее следует конструктор, и его установка позволяет вызывающей стороне указать начальное значение с параметрами конструктора.

public class Test {
   private String foo = "default String";
   private int bar = 0;

   public Test() {
   }
   public Test(String specificString) {
      this.foo = specificString;
   }

   public void fooMethod() {...} 
}

В этом примере foo инициализируется по умолчанию, если вы используете пустой конструктор (или если подкласс явно не вызывает его конструктор), тогда как если вы передаете String конструктору, это перезаписывает значение по умолчанию. bar получает значение по умолчанию, 0, независимо от того, какой конструктор вызывается.