Строка в Int в Java - вероятно, плохие данные, нужно избегать исключений - PullRequest
37 голосов
/ 06 октября 2008

Видя, что в Java нет обнуляемых типов и нет TryParse (), как вы обрабатываете проверку входных данных без исключения?

Обычный способ:

String userdata = /*value from gui*/
int val;
try
{
   val = Integer.parseInt(userdata);
}
catch (NumberFormatException nfe)
{
   // bad data - set to sentinel
   val = Integer.MIN_VALUE;
}

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

Как лучше всего справляться с этой ситуацией?

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

Дополнительные правки:

Некоторые из ответов наглядно демонстрируют, что не так с SO. Вы игнорируете задаваемый вопрос и отвечаете на другой вопрос, который не имеет к этому никакого отношения. Вопрос не о переходе между слоями. Вопрос не в том, что вернуть, если число не разбирается. Для всего, что вы знаете, val = Integer.MIN_VALUE; это точно правильный вариант для приложения, из которого был взят этот полностью контекстно-свободный фрагмент кода.

Ответы [ 16 ]

0 голосов
/ 03 декабря 2010

Integer.MIN_VALUE как NumberFormatException - плохая идея.

Вы можете добавить предложение в Project Coin, чтобы добавить этот метод в Integer

@ Обнуляемое общедоступное статическое Integer parseInteger (String src) ... при неправильном вводе возвращается ноль

Тогда поместите ссылку на ваше предложение здесь, и мы все проголосуем за него!

PS: посмотрите на это http://msdn.microsoft.com/en-us/library/bb397679.aspx это как уродливо и раздутый это может быть

0 голосов
/ 06 октября 2008

Механизм исключений является ценным, поскольку это единственный способ получить индикатор состояния в сочетании со значением ответа. Кроме того, индикатор состояния стандартизирован. Если есть ошибка, вы получаете исключение. Таким образом, вам не нужно думать об индикаторе ошибок самостоятельно. Противоречие происходит не столько с исключениями, сколько с Проверенными исключениями (например, теми, которые вы должны поймать или объявить).

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

Если вы не хотите иметь дело с исключением, просто оберните его в RuntimeException (или производный класс), и это позволит вам игнорировать исключение в вашем коде (и убивать ваше приложение, когда оно возникает; это тоже нормально ).

Некоторые примеры того, как я буду обрабатывать исключения NumberFormat: В данных конфигурации веб-приложения:

loadCertainProperty(String propVal) {
  try
  {
    val = Integer.parseInt(userdata);
    return val;
  }
  catch (NumberFormatException nfe)
  { // RuntimeException need not be declared
    throw new RuntimeException("Property certainProperty in your configuration is expected to be " +
                               " an integer, but was '" + propVal + "'. Please correct your " +
                               "configuration and start again");
    // After starting an enterprise application the sysadmin should always check availability
    // and can now correct the property value
  }
}

В графическом интерфейсе:

public int askValue() {
  // TODO add opt-out button; see Swing docs for standard dialog handling
  boolean valueOk = false;
  while(!valueOk) {
    try {
      String val = dialog("Please enter integer value for FOO");
      val = Integer.parseInt(userdata);
      return val; 
    } catch (NumberFormatException nfe) {
      // Ignoring this; I don't care how many typo's the customer makes
    }
  }
}

В веб-форме: вернуть форму пользователю с полезным сообщением об ошибке и возможностью правильный. Большинство платформ предлагают стандартизированный способ проверки.

0 голосов
/ 06 октября 2008

Если вы можете избежать исключений, предварительно протестировав, как вы сказали (isParsable ()), это может быть лучше - но не все библиотеки были разработаны с учетом этого.

Я использовал твой трюк, и он отстой, потому что следы стека на моей встроенной системе печатаются независимо от того, ловишь ты их или нет: (

0 голосов
/ 06 октября 2008

Приведенный выше код плох, потому что он эквивалентен следующему.

// this is bad
int val = Integer.MIN_VALUE;
try
{
   val = Integer.parseInt(userdata);
}
catch (NumberFormatException ignoreException) { }

Исключение полностью игнорируется. Кроме того, магический токен плох, поскольку пользователь может передать -2147483648 (Integer.MIN_VALUE).

Общий анализируемый вопрос не полезен. Скорее, это должно соответствовать контексту. Ваша заявка имеет определенные требования. Вы можете определить свой метод как

private boolean isUserValueAcceptable(String userData)
{
   return (    isNumber(userData)    
          &&   isInteger(userData)   
          &&   isBetween(userData, Integer.MIN_VALUE, Integer.MAX_VALUE ) 
          );
}

Где вы можете документировать требования и создавать четко определенные и проверяемые правила.

0 голосов
/ 06 октября 2008

Вы можете использовать целое число, которое может быть установлено равным нулю, если у вас неверное значение. Если вы используете Java 1.6, он обеспечит вам автоматическую коробку / распаковку.

0 голосов
/ 06 октября 2008

Поместите некоторые операторы if перед ним. if (null! = userdata)

...