Java: нормально ли устанавливать Integer = null? - PullRequest
10 голосов
/ 24 января 2010

У меня есть функция, которая возвращает номер идентификатора, если аргумент существует в базе данных. Если нет, возвращается ноль. Это просьба об исключении нулевого указателя? Отрицательные идентификаторы недопустимы, но я подумал, что было бы понятнее иметь несуществующие аргументы, возвращающие ноль вместо кода ошибки, например -1. Что ты думаешь?

private Integer tidOfTerm(String name) throws SQLException {
    String sql = "SELECT tid FROM term_data WHERE name = ?";
    PreparedStatement prep = conn.prepareStatement(sql);
    prep.setString(1, name);
    ResultSet result = prep.getResultSet();

    if (result.next()) {
        return result.getInt("tid");
    }

    return null; // TODO: is this begging for a null pointer exception?
}

Ответы [ 14 ]

15 голосов
/ 24 января 2010

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

3 голосов
/ 24 января 2010

Возвращение null в случае поиска, который не дает результата, является обычным способом представления несуществования. Я бы выбрал это в этом случае. (Методы поиска для стандартных классов Java Map являются примером использования null в случае, если карта не содержит ключа.)

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

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

2 голосов
/ 24 января 2010

Я думаю, что в этом случае допустимо возвращать ноль. Просто убедитесь, что намерение задокументировано правильно.

Возвращение отрицательного значения в этом случае было бы нормально, но это не всестороннее решение. Что если в БД разрешены отрицательные значения?

РЕДАКТИРОВАТЬ : Я хочу добавить слово о связанных обсуждениях на SO, касающихся возврата пустых или пустых списков (или массивов). Я за возвращение пустых списков или массивов вместо нуля, но контекст отличается. При попытке получить список он обычно является частью родительского объекта, и для родительского объекта имеет смысл иметь пустой список вместо пустой ссылки. В этом случае значение null имеет значение (= не найдено), и нет причин не возвращать его.

1 голос
/ 25 января 2010

Я предлагаю вам рассмотреть вариант шаблона.

Шаблон option действует как обертка для возвращаемого типа и определяет два особых случая: option.none () и option.some (). Таким образом, вы всегда знаете возвращаемый тип (параметр) и можете проверить, есть ли у вас значение в возвращенном объекте Option, используя такие методы, как option.isSome () и option.isNone ().

Таким образом, вы можете гарантировать отсутствие непроверенных значений.

Конечно, все это происходит за счет дополнительной сложности кода.

Для получения дополнительной информации о типе параметра см. здесь (код Scala, но тот же принципал)

1 голос
/ 24 января 2010
  • Не используйте код ошибки! Какое значение является ошибкой? никогда не станет законным возвращаемым значением? Ничего не победило.

  • Ноль это не хорошо. Большинству кода вызывающей стороны приходится делать проверку результата, если не нулевое. И иногда выбор может возвращать ноль. Должен ли он обрабатываться иначе, чем без строки?

  • Бросить исключение, подобное NoSuchElementException, вместо возвращаемого значения NULL. Это непроверенное исключение, вызывающий абонент может обработать его или передать его. И если вызывающий объект хочет обработать, то попытка catch не сложнее, чем if not null.

1 голос
/ 24 января 2010

Я надеюсь, что это не настоящий метод для вас. Вы не закрываете Statement или ResultSet в области видимости метода.

0 голосов
/ 25 января 2010

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

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

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

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

0 голосов
/ 25 января 2010

Интересная проблема и большое количество возможных решений:

  1. Создайте метод HasArgument и потребуйте, чтобы пользователи вызывали его, проблема может быть медленной и дублирующей.
  2. Бросить исключение, если значение отсутствует в базе данных, следует использовать только в том случае, если это неожиданно
  3. Используйте дополнительные значения, чтобы указать, что недопустимые возвращаемые значения, нулевые и отрицательные значения будут работать для вас, но если не отмечено, они могут вызвать проблемы позже в коде.
  4. Возвращает оболочку с методом isValid () и getValue (), где getValue () выдает исключение, когда оно недопустимо. Это решило бы проблемы 1 и 3, но может быть слишком много.
0 голосов
/ 24 января 2010

Пожалуйста, не пишите код, который возвращает ноль.Это означает, что каждый вызов вашего кода ДОЛЖЕН проверять наличие нуля, чтобы быть устойчивым.Каждый раз.Всегда.

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

0 голосов
/ 24 января 2010

Может быть сложно в комбинации с автобоксом. Если я делаю это:

final int tid = tidForTerm("term");

И «term» не существует, я получу NPE, потому что Java пытается распаковать Integer (null) в примитив int.

Тем не менее, бывают случаи, когда на самом деле полезно использовать null для целых чисел. В объектах, имеющих необязательные значения типа int, например население города. В этом случае ноль будет означать, что информация недоступна.

...