Как показать, может ли метод возвращать значение null

StackOverflow https://stackoverflow.com/questions/411447

  •  03-07-2019
  •  | 
  •  

Вопрос

После публикации этот вопрос и чтение Вон тот Я понял, что очень важно знать, должен ли метод возвращать значение null или это считается состоянием ошибки и следует генерировать исключения.Также есть приятная дискуссия, когда вернуть «ноль» или выдать исключение .

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

Некоторые способы, о которых я могу думать:

  • Запишите это в спецификациях/документации (кто-нибудь прочитает?)
  • Сделайте это частью имени метода (как я предложил здесь)
  • предполагать, что каждый метод, который бросает исключение будет нет вернуть ноль, и все, что «не» выбрасывает мощь вернуть ноль.

В основном я говорю о Java, но это может относиться и к другим языкам:Почему существует формальный способ выразить, будут ли возникать исключения ( throws ключевые слова), но нет формального способа выразить, может ли быть возвращено значение null?

Почему нет такого:

public notnull Object methodWhichCannotReturnNull(int i) throws Exception
{
    return null; // this would lead to a compiler error!
}

Резюме и заключение

Существует множество способов выразить договор:

  • Если ваша IDE поддерживает это (как IntelliJ), лучше всего использовать аннотацию типа @NotNull потому что он виден программисту и может использоваться для автоматической проверки времени компиляции.Есть плагин для Eclipse чтобы добавить их поддержку, но у меня это не сработало.
  • Если это невозможно, используйте пользовательские типы, например Option<T> или NotNull<T>, которые добавляют ясности и, по крайней мере, проверки во время выполнения.
  • В любом случае документирование контракта в JavaDoc никогда не помешает, а иногда даже помогает.
  • Использование имен методов для документирования обнуляемость возвращаемого значения не был предложен никем, кроме меня, и хотя он может быть очень многословным и не всегда полезным, я все же верю, что иногда у него тоже есть свои преимущества.
Это было полезно?

Решение

Очень хороший дополнительный вопрос.я полагаю null действительно особое значение, и если метод может вернуть null когда это происходит, он должен четко документироваться в Javadoc (@return some value ..., or null if ...).При кодировании я защищаюсь и предполагаю, что метод может вернуть результат. null если я не убежден, что это невозможно (например, потому что так сказано в Javadoc).

Люди поняли, что это проблема, и предлагаемое решение — использовать аннотации для формулирования намерения таким образом, чтобы его можно было проверить автоматически.Видеть JSR 305:Аннотации для обнаружения дефектов программного обеспечения, JSR 308:Аннотации к типам Java и Nullable How-To от JetBrain.

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

@NotNull
public Object methodWhichCannotReturnNull(int i) throws Exception
{
    return null; // this would lead to a compiler error!
}

Другие советы

Вы можете использовать Option type, который очень похож на список, содержащий ноль или один элемент.Возвращаемый тип Option<Object> указывает, что метод может возвращать Object, или он может возвращать специальное значение типа None.Этот тип является заменой использования null с улучшенными проверками типов.

Пример:

public Option<Integer> parseInt(String s) {
   try {
      return Option.some(Integer.parseInt(s));
   }
   catch (Exception e) {
      return Option.none();
   }
}

Если вы используете это постоянно, вы можете включить нулевые предупреждения IDE или просто использовать grep для null который вообще не должен появляться в вашем коде, если вы используете Option.none() везде, где вы обычно используете null буквально.

Option входит в стандартную комплектацию Scala и называется Maybe в Хаскеле.Ссылка выше относится к библиотеке под названием Функциональная Java это включает в себя.Эта версия реализует Iterable интерфейс и имеет монадические методы, позволяющие красиво компоновать вещи.Например, чтобы предоставить значение по умолчанию 0 в случае None:

int x = optionalInt.orSome(0);

И это можно заменить...

if (myString != null && !"".equals(myString))

...с этим, если у вас есть Option<String>...

for (String s : myOptionString)

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

Я вижу три варианта:

  1. дождитесь языковой поддержки, чтобы выразить это (например.тот С#?! вещь)
  2. используйте аспектную ориентацию для создания собственных языковых расширений для ее выражения.
  3. используйте собственный тип, чтобы выразить это
  4. (но основано на сотрудничестве разработчиков) используйте схему именования для обозначения этого

В Java можно использовать описание метода в документации Javadoc, чтобы документировать значение возвращаемого значения, включая то, может ли оно быть нулевым.Как уже упоминалось, здесь также могут помочь аннотации.

С другой стороны, я признаю, что не считаю null чем-то, чего следует опасаться.Бывают ситуации, в которых «ничтожного дома» является значимым условием (хотя техника Null Object также имеет здесь реальную ценность).

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

Вы взглянули на Спецификация#?

Вы можете написать собственную аннотацию (Java) или атрибут (C#), чтобы указать, что возвращаемое значение может быть нулевым.Ничто не будет проверять это автоматически (хотя в .NET 4.0 будет кодовые контракты для такого рода вещей), но это, по крайней мере, будет служить документацией.

Есть некоторая поддержка Аннотация @Nullable и @NotNull в IntelliJ IDEA.Также ходят разговоры о добавлении этих аннотаций (или аналогичной функции) в Java 7.К сожалению, я не знаю, как далеко это зашло и продолжается ли вообще.

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

public NotNull<Object> methodWhichCannotReturnNull(int i) throws Exception
{
   // the following would lead to a run-time error thown by the
   // NotNull constructor, if it's constructed with a null value
   return new NotNull<Object>(null);
}

Это все еще проверка во время выполнения (а не во время компиляции), но:

  • Он выбрасывается при реализации метода (это не ошибка в вызывающем коде)
  • Это самодокументируется (звонящий знает, что он получает NotNull<T> в качестве возвращаемого типа)

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

Если вы используете Java 5+, вы можете использовать собственную аннотацию, например.@MayReturnNull

ОБНОВЛЯТЬ

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

Вообще говоря, я бы предположил, что нулевое возвращаемое значение по умолчанию противоречит контракту API.Почти всегда можно спроектировать код так, чтобы нулевое значение никогда не возвращалось из ваших API во время «нормального» потока выполнения.(Например, проверьте foo.contains(obj), а не вызывайте foo.get(obj) и создайте отдельную ветку для null.Или воспользуйтесь Шаблон нулевого объекта.

Если вы не можете спроектировать свой API таким образом, я бы четко описал, когда и почему может быть выброшено значение null - в наименее в Javadoc и, возможно, также с использованием специальной @annotation, как предлагалось в некоторых других ответах.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top