什么是 NumberFormatException 以及如何修复它?

新手上路,请多包涵
Error Message:
Exception in thread "main" java.lang.NumberFormatException: For input string: "Ace of Clubs"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:580)
    at java.lang.Integer.parseInt(Integer.java:615)
    at set07102.Cards.main(Cards.java:68)
C:\Users\qasim\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)

我的 While 循环:

 while (response != 'q' && index < 52) {
    System.out.println(cards[index]);
    int first_value = Integer.parseInt(cards[index]);
    int value = 0;
    //Add a Scanner
    Scanner scanner = new Scanner(System.in);
    System.out.println("Will the next card be higher or lower?, press q if you want to quit");
    String guess = scanner.nextLine();
    if(cards[index].startsWith("Ace")) { value = 1; }
    if(cards[index].startsWith("2")) { value = 2; }
    if(cards[index].startsWith("3")) { value = 3; }
    //checking 4-10
    if(cards[index].startsWith("Queen")){ value = 11; }
    if(cards[index].startsWith("King")){ value = 12; }
    if(guess.startsWith("h")){
        if(value > first_value){ System.out.println("You answer was right, weldone!"); }
        else { System.out.println("You answer was wrong, try again!"); }
    } else if(guess.startsWith("l")){
        if(value < first_value) { System.out.println("You answer as right, try again!"); }
        else { System.out.println("You answer was wrong, try again!"); }
    } else { System.out.println("Your was not valid, try again!"); }
    scanner.close();
    index++;
}//end of while loop

原文由 Qasim Imtiaz 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
1 个回答
Error Message:
Exception in thread "main" java.lang.NumberFormatException: For input string: "Ace of Clubs"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:580)
    at java.lang.Integer.parseInt(Integer.java:615)
    at set07102.Cards.main(Cards.java:68)
C:\Users\qasim\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1

方法:

 There was an error. We try to give you as much information as possible
It was an Exception in main thread. It's called NumberFormatException and has occurred for input "Ace of Clubs".
at line 65th of NumberFormatException.java which is a constructor,
which was invoked from Integer.parseInt() which is in file Integer.java in line 580,
which was invoked from Integer.parseInt() which is in file Integer.java in line 615,
which was invoked from method main in file Cards.java in line 68.

It has resulted in exit code 1

换句话说,您试图将 "Ace of Clubs" 解析为 int Java 不能用方法 Integer.parseInt 做的事情。 Java 提供了漂亮的堆栈跟踪,可以准确地告诉您问题出在哪里。您正在寻找的工具是 调试器,使用 断点 将允许您在选定的时刻检查应用程序的 _状态_。

如果您想使用 _解析_,解决方案可能是以下逻辑:

 if (cards[index].startsWith("Ace"))
    value = 1;
else if (cards[index].startsWith("King"))
    value = 12;
else if (cards[index].startsWith("Queen"))
    value = 11;
...
else {
    try {
        Integer.parseInt(string.substring(0, cards[index].indexOf(" ")));
    } catch (NumberFormatException e){
        //something went wrong
    }
}

Java 中的 Exception 是什么?

异常是在程序执行期间发生的事件,它会破坏程序指令的正常流程。

- 文档

Integer\#parseInt

 static NumberFormatException forInputString(String s) {
    return new NumberFormatException("For input string: \"" + s + "\"");
}

public NumberFormatException (String s) {
    super (s);
}

它们对于理解如何读取堆栈跟踪很重要。看看 NumberFormatException 是如何从 Integer#parseInt 抛出的:

 if (s == null) {
    throw new NumberFormatException("null");
}

或者稍后,如果输入的格式 String s 不可解析:

 throw NumberFormatException.forInputString(s);

什么是 NumberFormatException

抛出以指示应用程序已尝试将字符串转换为其中一种数字类型,但该字符串没有适当的格式。

- 文档

NumberFormatException extends IllegalArgumentException 。它告诉我们它更专业 IllegalArgumentException 。事实上,它用于强调虽然参数类型是正确的( StringString 的内容不是数字( _a,b,c,d,e,f被认为是 HEX 中的数字,并且在需要时是合法的_)。

我如何解决它?

好吧,不要修复它被抛出的事实。扔了就好了。您需要考虑一些事项:

  1. 我可以读取堆栈跟踪吗?
  2. String 导致 Exception a null 吗?
  3. 它看起来像一个数字吗?
  4. 是“我的字符串”还是用户的输入?
  5. 未完待续

广告。 1.

消息的第一行是异常发生的信息和导致问题的输入 String 。字符串始终跟在 : 并被引用 ( "some text" )。然后你开始有兴趣从最后阅读堆栈跟踪,因为前几行通常是 NumberFormatException 的构造函数、解析方法等。最后,你的方法中出现了错误。会指出是在哪个文件中调用的,是在哪个方法中调用的。甚至连线都会附上。你会看到的。上面是如何读取堆栈跟踪的示例。

广告。 2.

当你看到,而不是 "For input string:" 和输入时,有一个 null不是 "null" )它意味着你试图传递空值一个号码。如果您真的想将 is 视为 0 或任何其他数字,您可能会对我在 StackOverflow 上的另一篇文章感兴趣。可 在此处 获得。

解决意外的描述 null s 在 StackOverflow 线程上有很好的描述 什么是 NullPointerException 以及如何修复它? .

广告。 3.

如果 String: 并被引用在您看来看起来像一个数字,则可能存在您的系统无法解码的字符或看不见的空格。显然 " 6" 不能像 "123 " 一样被解析。这是因为空格。但它可能会发生,即 String 看起来像 "6" 但实际上它的长度将大于你可以看到的位数。

在这种情况下,我建议使用 调试器 或至少 System.out.println 并打印 String 您正在尝试解析的长度。如果它显示的数字多于位数,请尝试将 stringToParse.trim() 传递给解析方法。如果它不起作用,请复制 : 之后的整个字符串,并使用在线解码器对其进行解码。它会给你所有字符的代码。

我最近在 StackOverflow 上发现了一个案例,您可能会看到,输入看起来像一个数字,例如 "1.86" 它只包含这 4 个字符,但错误仍然存在存在。请记住,只能使用#Integer#parseInt# 解析整数。对于解析十进制数,应该使用 Double#parseDouble

另一种情况是,当数字有很多位时。它可能太大或太小而无法容纳 intlong 。您可能想尝试 new BigDecimal(<str>)

广告。 4.

最后我们来到了我们同意的地方,我们无法避免用户输入“abc”作为数字字符串的情况。为什么?因为他可以。在一个幸运的案例中,这是因为他是一名测试员或者只是一个极客。在糟糕的情况下,它是攻击者。

我现在能做什么? 好吧,Java 给了我们 try-catch 你可以这样做:

 try {
    i = Integer.parseInt(myString);
} catch (NumberFormatException e) {
    e.printStackTrace();
    //somehow workout the issue with an improper input. It's up to your business logic.
}

原文由 xenteros 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题