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

Java api design - NULL или исключение

Лучше ли вернуть значение null или исключить исключение из метода API?

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

Бросание исключения заставляет пользователя кодировать ошибочное условие, но поскольку исключения Java затухают и заставляют код вызывающего абонента обрабатывать их, в общем случае использование пользовательских исключений может быть плохой идеей (особенно в java).

Любые звуковые и практические советы?

4b9b3361

Ответ 1

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

Например, если вы пишете XML-парсер, вы можете реализовать такие методы, как:

/**
 * Returns first child element with matching element name or else
 * throws an exception.  Will never return null.
 */
Element getMandatoryChildElement(Element parent, String elementName)
throws MissingElementException;

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

Ответ 2

Если null является допустимым возвращаемым значением (т.е. оно может быть результатом корректных входов, а не ошибок), верните null; иначе выведите исключение.

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

Ответ 3

Джош Блох рекомендует возвращать пустые объекты или "единичные" объекты вместо нулевых значений. Проверьте Эффективную Java за тонну полезных кусочков Java.

Ответ 4

Я хочу сказать, что

Никогда не возвращать NULL при возврате type - это коллекция или массив. Если нет возвращаемого значения, верните пустую коллекцию или пустой массив.

Это устраняет необходимость нулевой проверки.

Хорошая практика:

public List<String> getStudentList()
{
     int count = getStudetCount();
     List<String> studentList = new ArrayList<String>(count);
     //Populate studentList logic
     return studentList;
}

Плохая практика:. Никогда не пишите код, как показано ниже.

public List<String> getStudentList()
{
     int count = getStudetCount();
     if(count == 0)
     {
         return null;
     }
     //Populate studentList logic
     return studentList;
}

Ответ 5

В Практический дизайн API автор советует не возвращать значение null (см. стр .24).

Его основной момент состоит в том, что он приводит к увеличению количества проверок в отношении значения null и дополнительной документации.

Я также настоятельно рекомендую прочитать "Null References: Billion Dollar Mistake "авторитетом в этой области (Т. Хоар).

Ответ 6

Я склонен возвращать null методам getXXX, которые, например, извлекают что-то из базы данных example: User getUserByName (String name) в порядке для возврата null

Но, если вам НЕОБХОДИМО, что вы выберете, вызвав метод, выполните исключение: ex: getDatabaseConnection() должен всегда возвращать соединение и никогда не возвращать null

И для методов, возвращающих коллекцию или массив, НИКОГДА не возвращайте значение null. верните пустую коллекцию/массив вместо

Ответ 7

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

Ответ 8

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

Если вы ожидаете, что что-то (иногда) пойдет не так, создайте это в API. Это основано на принципе, что вы не должны использовать исключения для нормального потока программы.

Например:

ProcessResult performLibraryTask(TaskSpecification ts)

Таким образом, вы можете иметь ProcessResult указать условия ошибки:

ProcessResult result = performLibraryTask(new FindSmurfsTaskSpecification(SmurfColor.BLUE));
if (result.failed()) {
    throw new RuntimeException(result.error());
}

Этот подход похож на обратный нулевой подход, но вы можете отправить дополнительную информацию клиенту.

ИЗМЕНИТЬ:

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

if (currentPeriod().equals(SmurfColor.BLUE) && SmurfColor.GREEN.equals(taskSpecification.getSmurfColor()) {
    throw new IllegalStateException("Cannot search for green smurfs during blue period, invalid request");
}

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

Ответ 9

A согласуются с остальными, если null является допустимым возвращаемым значением, верните его, но в противном случае это не так.

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

Ответ 10

Обычно я рассматриваю аналогичный пример в JDK.

В случае аксессуаров имеет смысл использовать Null.

Нуль следует использовать для указания отсутствующих или неизвестных данных.

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

Теперь у нас есть 2 варианта, время выполнения и время компиляции. Вот примеры того, как я ищу аналогию.

Позволяет извлечь пример из ArrayIndexOutOfBoundException. Доступ или изменение элемента - очень распространенная операция.

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

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