Значение по умолчанию для определения ошибки синтаксического анализа (String -> double / any numeric) - PullRequest
1 голос
/ 10 мая 2019

Какова наилучшая практика в Java для проверки на недопустимые результаты анализа при использовании «значения по умолчанию» вместо исключений?

(Старый) проект, над которым я работаю, имеет отказоустойчивый утилитный метод для анализа String в double, например:

//null checks, LOG output etc removed for readability
double parseDouble(String input, double defaultValue){ 
  try{    
    return Double.parseDouble(input)
  } catch (Exception e){
    return defaultValue;
  }
}

Теперь предыдущий разработчик(s) всегда использовали значение по умолчанию, например returnedValue = parseDouble(someString, -99);, и проверку, например if(returnedValue == -99), для определения неверного результата анализа.(Наконец) добавленный сервер SonarQube жалуется на эту проверку, используя == на double, и я хочу заменить эти проверки "правильной" проверкой.

Как лучше всего обрабатывать такие случаи?

Я бы лично использовал parseDouble(someString, Double.NaN); и соответственно чек if(Double.isNan(returnedValue).Это жизнеспособное решение?

EDIT : я забыл упомянуть, что служебный класс не редактируется (с моей точки зрения), и поэтому я ищу, как легко "исправить"существующий код.Также было бы неплохо добавить сторонние библиотеки, но это (на данный момент) также невозможно.

1 Ответ

0 голосов
/ 10 мая 2019

В старые времена я также пошел бы с NAN или POSITIVE_INFINITY или MAX_VALUE или любым другим, который не используется. Теперь я бы использовал Optional-класс. Использование целых чисел не является надежным из-за преобразования, а использование null - это ошибка Hoares на один миллиард долларов: означает ли null ошибку, не инициализированную, не заданную? Была ли входная строка нулевой или она была проанализирована, и это не было допустимым двойным представлением?

Как правило, вам не нужен метод, который возвращает значение по умолчанию, если произошла ошибка синтаксического анализа или введен нулевой ввод или пользователь ввел значение по умолчанию. Вам нужен метод, который возвращает вам информацию, была ли ошибка или нет, а если нет, то проанализированное значение. Чтобы сделать ваш код более читабельным и легким для понимания, я бы написал именно такой метод и использовал его везде, где это необходимо (вместо обходных путей для копирования). Если вы не можете поместить его в существующий служебный класс, создайте свой собственный дополнительный служебный класс. Если вы используете Java 8, вы можете использовать Optional-класс. Если нет, то запрограммируйте свой собственный Optional (или возьмите его из какой-нибудь библиотеки) Вот полезный метод:

Optional<Double> parseDouble(String input) { 
  try {    
    return Optional.of(Double.parseDouble(input));
  } catch (Exception e) {
    return Optional.empty();
  }
}

Вот как это использовать:

String input = ...;
Optional<Double> parsedInput = parseDouble(input);
if (! parsedInput.isPresent()) {
    // print out warning and retry input or whatever
}
double convertedInput = parsedInput.value();

Примечание:

SonarQube также критиковал бы поймать общее "Исключение". Вместо этого вы должны поймать NumberFormatException и NullPointerException. Когда вызывающая сторона должна знать точную причину, вы можете добавить метод getEmptyReason () в ваш Optional (или производный класс) и сохранить там причину исключения. Но я предполагаю, что в вашем случае вы хотите использовать значение по умолчанию, если входная строка не была задана (пустая или пустая), и хотите обработать ошибку, если значение было задано, но не разборчиво. В этом случае вы можете использовать:

Optional<Double> parseDouble(String input, double defaultValue) { 
  if (input == null || input.trim().length == 0) {
    return Optional.of(defaultValue);
  }
  try {    
    return Optional.of(Double.parseDouble(input));
  } catch (NumberFormatException e) {
    return Optional.empty();
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...