Есть ли разница между этими двумя режимами инициализации? - PullRequest
2 голосов
/ 06 января 2010

Допустим, у меня есть это:

public class Whatever {
   private ArrayList<String> myList = new ArrayList<String>();
   // more code goes here
}

или скажем, у меня есть это:

public class Whatever {
   private ArrayList<String> myList = null;

   public Whatever() {
     myList = new ArrayList<String>();
   }
}

В чем разница между этими двумя инициализациями myList? Было бы неправильно указывать первый вариант?

Ответы [ 3 ]

13 голосов
/ 06 января 2010

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

public class Whatever {
   private final List<String> myList;

   public Whatever() {
     myList = new ArrayList<String>();
   }

   public Whatever(String name) {
     this();
     // Other stuff done
   }

   public Whatever(List<String> myList) {
     this.myList = myList;
   }
}

(Второй) «ленивый» метод инициализации может быть лучше, если вы не всегда используете список (например, если вы устанавливаете список в другом конструкторе, как в моем примере) и хотите избежать создания ненужных объектов. (РЕДАКТИРОВАТЬ: я изменил ArrayList на интерфейс и установил его окончательно. Это не было частью вопроса, но это - как упоминалось в комментариях - лучший способ использовать коллекции List).

3 голосов
/ 06 января 2010

В этом конкретном примере нет разницы, за исключением того, что первая форма короче.

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

И, конечно, если у вас есть несколько конструкторов, вторая форма позволяет вам по-разному инициализировать атрибут в каждом конструкторе ... или использовать цепочку конструктора для инициализации атрибута одинаково ... или смешивать два стиля инициализации.

3 голосов
/ 06 января 2010

JVM сначала выполняет такой код (вне конструктора):

public class Whatever {
   private ArrayList<String> myList = new ArrayList<String>();
   // more code goes here
}

И только потом такой код (внутри конструктора):

public class Whatever {
   private ArrayList<String> myList = null;

   public Whatever() {
     myList = new ArrayList<String>();
   }
}

Так что, если порядок исполнения не так важен для вас, я думаю, @ ответ Даффа правильный.

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