Java api design - NULL или исключение
Лучше ли вернуть значение null или исключить исключение из метода API?
Возврат нуля требует уродливых нулевых проверок на всем протяжении и вызывает серьезную проблему с качеством, если возврат не проверен.
Бросание исключения заставляет пользователя кодировать ошибочное условие, но поскольку исключения Java затухают и заставляют код вызывающего абонента обрабатывать их, в общем случае использование пользовательских исключений может быть плохой идеей (особенно в java).
Любые звуковые и практические советы?
Ответы
Ответ 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, и ее можно избежать, написав хороший код.
На обратной стороне, если у нас есть кусок кода, который открывает файл, который может быть вызван из-за внешних зависимостей (отсутствующий файл или не имеющий достаточных привилегий) и не укорененный в ошибках в программах, это хорошая идея проверили исключение.