В чем разница между этими двумя способами инициализации полей в Java? - PullRequest
2 голосов
/ 17 марта 2011
  1. Присвоить значение полю одновременно с объявлением поля
  2. Назначить значение полю в конструкторе?

Ответы [ 5 ]

7 голосов
/ 17 марта 2011

В чем разница между этими двумя способами инициализации полей в Java?

Не очень! Основное отличие состоит в том, что если вы назначите его в точке объявления, он будет применяться к всем конструкторам. То есть вы никак не можете забыть добавить инициализацию в любые будущие конструкторы.

Посмотрите официальные поля инициализации след.

Может быть стоит отметить, что если вы инициализируете поля в объявлении, это произойдет за до того, как конструктор начнет выполняться.

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

class SomeClass {

    List<Integer> currentNumbers = new ArrayList<Integer>();
    int counter = 0;

    // ...
}

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

4 голосов
/ 17 марта 2011

В обоих случаях значение будет назначено только после , который выполнил конструктор суперкласса.

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

Для второго варианта вам нужно будет присвоить значение в каждой перегрузке конструктора.

В основном я предпочитаю второй вариант, когда значениезависит от параметров конструктора (обычно это все, от чего я бы хотел зависеть) и от первого варианта, когда значение будет одинаковым для любого вновь инициализированного экземпляра.Я склонен не смешивать и сопоставлять для одного поля, используя инициализатор с объявлением и также , назначая его в некоторых перегрузках конструктора, но даже это может быть полезно иногда.(Представьте себе коллекцию, которая имеет размер 0 для большинства конструкторов, но имеет один конструктор, который принимает начальный набор значений.)

Пока вы можете ссылаться на другие члены экземпляра в объявлениях переменныхЯ предпочитаю не делать этого - вызов методов экземпляра, когда ваш объект только частично инициализирован, является хрупким, а обращение к другим переменным зависит от порядка переменных, что мне неприятно.

1 голос
/ 17 марта 2011

(1) является синтаксическим сахаром для (2) (за исключением статических полей)

0 голосов
/ 17 марта 2011

В первом случае поле будет создано, когда класс будет инициализирован и ему будет присвоено значение, которое вы объявили для него, а во втором случае поле будет создано и ему будет присвоено значение по умолчанию (ноль, если это объект 0, если это int и т. Д.), А затем присваивается правильное значение при выполнении конструктора. Конечно, практически нет особой разницы для вас, поскольку результат в обоих случаях одинаков: когда вы создаете экземпляр этого класса после того, как конструктор возвращает поле, поле инициализируется правильно. Я думаю, что первый подход был бы более полезным, если у вас есть более одного конструктора и поле, которое должно иметь одинаковое значение независимо от того, какой конструктор был вызван.

0 голосов
/ 17 марта 2011

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

...