Вопрос

У меня есть функция, которая возвращает идентификационный номер, если аргумент существует в базе данных.Если нет, он возвращает ноль.Это требует исключения нулевого указателя?Отрицательные числа идентификаторов не допускаются, но я подумал, что было бы яснее иметь несуществующие аргументы, возвращающие ноль вместо кода ошибки, например -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?
}
Это было полезно?

Решение

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

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

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

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

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

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

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

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

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

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

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

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

Предлагаю вам рассмотреть опционный паттерн.

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

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

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

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

Нет, не будет.Он выдаст NPE только в том случае, если вы впоследствии выполните с ним операции, как если бы это был примитив, без проверки его на ноль.Например. i++ и так далее.Ваш пример действителен (ожидайте, что из самого кода JDBC происходит утечка ресурсов).Если вам не нужен настоящий id, тогда вы также можете просто вернуть boolean.

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

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

final int tid = tidForTerm("term");

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

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

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

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

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

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

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

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

Согласен с плакатами.Integer — это оболочка, и поэтому его следует использовать для вычислений, преобразований и т. д. (что, я думаю, вы и собираетесь сделать).Не возвращайте ноль, используйте отрицательное число...это немного более элегантно и дает вам больше контроля.ИМХО.

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

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

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

Возврат кода ошибки (например, -1) бесполезен, потому что:

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

б) если в будущем -1 станет допустимым идентификатором термина, его будет трудно изменить (если вам необходимо использовать -1, тогда (EDIT:в C) хотя бы #define ERRORCODE -1 и везде используйте ERRORCODE)

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