Существует ли соглашение Java для возврата true, false или unknown?

Я пишу метод, который будет возвращаться, если что-то верно или нет. Но если ресурсы, необходимые для проверки условия, недоступны, оно не сможет вернуть значение true или false.

Раньше я просто делал метод, который возвращает boolean. Но теперь, чтобы учесть исключения, я думаю передать true или false в аргументах функции и использовать возвращаемое значение в качестве индикатора успеха или неудачи для теста.

Это «правильный и распространенный» способ сделать это на Java? Или что-то еще распространено в Java для достижения этой цели?


person xyz    schedule 07.10.2011    source источник
comment
Можете ли вы предоставить немного больше контекста? Прямо сейчас это звучит так, как будто вам нужно логическое возвращаемое значение с проверенными или непроверенными исключениями... но трудно сказать наверняка.   -  person corsiKa    schedule 07.10.2011
comment
Что плохого в том, чтобы просто возвращать true или false и генерировать исключение в случае сбоя?   -  person NullUserException    schedule 07.10.2011
comment
Инверсия: как нельзя это делать: thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx   -  person yas4891    schedule 07.10.2011
comment
Вы не можете передать ссылку на boolean в Java, если это то, что вы имели в виду, передавая true/false в аргументах функции. Самое близкое, что вы можете получить, это передать некоторый изменяемый объект и изменить его.   -  person erickson    schedule 07.10.2011


Ответы (4)


Ваш метод должен возвращать логическое значение и генерировать Exception, если ресурсы недоступны.

person Asaph    schedule 07.10.2011
comment
Это правильно, при условии, что недоступные ресурсы являются исключительным состоянием. Если это нормальное и ожидаемое состояние, исключение не подходит. - person pamphlet; 08.01.2014

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

Теперь вам нужно решить, будет ли выбранное исключение проверено или не проверено. Это действительно зависит от контекста. Обычно я думаю так: если у вызывающего есть способ гарантировать, что метод не может дать сбой, я заставлю его генерировать непроверенное исключение; в противном случае, если у вызывающего абонента нет возможности быть абсолютно уверенным, что метод не сработает, я бы сделал его проверенным исключением.

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

class C1 {
  public boolean canCalculateResultNow() { ... }
  public boolean calculateResult() {
    if (cannot get resource) throw new IllegalStateException("Cannot get resource");
    ...
  }
}

Теперь вот что я бы сделал, если вызывающая сторона не может быть уверена, что метод сможет завершиться нормально:

class CannotCalculateResultException extends Exception { ... }
class C2 {
  public boolean calculateResult() throws CannotCalculateResultException {
    if (cannot calculate result) throw new CannotCalculateResultException();
    ...
  }
}

Другая возможность, которая мне очень не нравится и которую я категорически не одобряю, состоит в том, чтобы заставить метод возвращать Boolean, который является обнуляемой версией boolean. Boolean может быть true, false или null. Затем вы можете заставить метод возвращать null, если ресурс недоступен.

Основная проблема, которую я вижу в этом подходе, заключается в том, что значение null может быть неясным. Вызывающий код всегда должен будет проверять, является ли результат нулевым, и разработчик (возможно, даже вы сами через несколько месяцев после написания этого кода) должен будет прочитать документацию метода, чтобы узнать, что означает нулевой результат. Конкретное проверенное исключение абсолютно ясно показывает, что что-то может пойти не так и что может пойти не так. Кроме того, это заставит разработчика подготовиться к тому случаю, когда что-то пойдет не так. На подходе с непроверенными исключениями наличие метода canCalculateResult() также будет указывать разработчику, использующему класс, на то, что что-то может пойти не так, без необходимости читать документацию, и разумно предположить, что это что-то "опасное" для позвонить calculareResult() без предварительного звонка canCalculateResult().

person Bruno Reis    schedule 07.10.2011

Я бы предложил другой подход: возвращать не boolean, а Boolean и возвращать true/false когда есть ресурсы и возвращать null когда ресурсов нет

person Barmaley    schedule 07.10.2011

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

person marcocamejo    schedule 07.10.2011