TL;DR: используйте пустые коллекции, а не нули.

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

Если объект содержит коллекцию, и эта коллекция не имеет элементов, должна ли она быть представлена ​​коллекцией нулевой длины или нулевым значением? Разумной первой реакцией было бы просто оставить вещь нулевой, но это означает, что каждый, кто когда-либо использует эту коллекцию, должен сначала проверить, существует ли коллекция на самом деле:

if (myCar.getTires() != null) {
  foreach (Tire tire : myCar.getTires()) {
    tire.inflate();
  }
}

Если мы знаем, что коллекция всегда существует, даже если она может быть пустой, мы можем избежать этой проверки на null:

foreach (Tire tire : myCar.getTires()) {
 tire.inflate();
}

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

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

int sumTerms(Expression expression) {
  return expression.value + term.getTerms()
                                .stream()
                                .mapToInt(t -> sumTerms(t))
                                .sum();
}

Видите, никакой проверки на null, никаких исключений NullPointerException, ничего. Использование нулевых коллекций здесь только сделало бы код немного длиннее, немного труднее для чтения и немного более подверженным ошибкам. Только немного, да? Но кому это нужно, когда в этом нет необходимости?

Получайте удовольствие от кодирования!