воскресенье, 21 мая 2017 г.

Try. Finally. If. Not. Null.

Существует очень типичная ошибка в сценарии «try / finally» до Java7, который я продолжаю видеть во многих обзорах кода. Я просто должен написать об этом. Java7 представила решение, но оно не охватывает все ситуации. Иногда нам приходится иметь дело с неавтоматизированными ресурсами. Давайте откроем и закроем их правильно.

Вот как это выглядит (предположим, что мы на Java 6):
InputStream input = null;
try {
  input = url.openStream();
  // reads the stream, throws IOException
} catch (IOException ex) {
  throw new RuntimeException(ex);
} finally {
  if (input != null) {
    input.close();
  }
}
Я уже писал о null и его злой природе. Вот он снова. Если вы просто следуете правилу «не использовать NULL в любом месте», этот код нуждается в немедленном рефакторинге. Его правильная версия будет выглядеть так:

final InputStream input = url.openStream();
try {
  // reads the stream, throws IOException
} catch (IOException ex) {
  throw new RuntimeException(ex);
} finally {
  input.close();
}
Больше нет нулей, и это очень чисто. Не так ли?
Есть ситуации, когда открытие ресурса само бросает исключение IOException, и мы не можем вынести его за пределы try / catch. В этом случае мы должны иметь два блока try / catch:


final InputStream input;
try {
  input = url.openStream();
} catch (IOException ex) {
  throw new RuntimeException(ex);
}
try {
  // reads the stream, throws IOException
} catch (IOException ex) {
  throw new RuntimeException(ex);
} finally {
  input.close();
}
Никогда не должно быть null!
Наличие значения null в коде Java является явным индикатором дурно пахнущего запаха кода. Что-то не так, если вам нужно использовать null. Единственное место, где наличие null является оправданным, - это то, где мы используем сторонние API или JDK. Иногда они могут возвращать null, потому что ... ну, их конструкция плохая. У нас нет другого выбора, кроме как если (x == null). Но это все. Ни одно другое место не подходит для нулей.

Комментариев нет:

Отправить комментарий