什么是 NumberFormatException 以及如何修复它? [英] What is a NumberFormatException and how can I fix it?

查看:76
本文介绍了什么是 NumberFormatException 以及如何修复它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

错误信息:线程main"中的异常 java.lang.NumberFormatException:对于输入字符串:Ace of Clubs"在 java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)在 java.lang.Integer.parseInt(Integer.java:580)在 java.lang.Integer.parseInt(Integer.java:615)在 set07102.Cards.main(Cards.java:68)C:\Users\qasim\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53:Java 返回:1构建失败(总时间:0 秒)

我的 While 循环:

while (response != 'q' && index <52) {System.out.println(卡片[索引]);int first_value = Integer.parseInt(cards[index]);整数值 = 0;//添加扫描器扫描仪scanner = new Scanner(System.in);System.out.println("下一张牌是高还是低,要退出按q");字符串猜测 = 扫描仪.nextLine();if(cards[index].startsWith("Ace")) { value = 1;}if(cards[index].startsWith("2")) { value = 2;}if(cards[index].startsWith("3")) { value = 3;}//检查4-10if(cards[index].startsWith("Queen")){ value = 11;}if(cards[index].startsWith("King")){ value = 12;}if(guess.startsWith("h")){if(value > first_value){ System.out.println("你的答案是对的,weldone!");}else { System.out.println("你答错了,再试一次!");}} else if(guess.startsWith("l")){if(value < first_value) { System.out.println("你回答正确,再试一次!");}else { System.out.println("你答错了,再试一次!");}} else { System.out.println("你的无效,再试一次!");}扫描仪关闭();指数++;}//while循环结束

解决方案

错误信息:线程main"中的异常 java.lang.NumberFormatException:对于输入字符串:Ace of Clubs"在 java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)在 java.lang.Integer.parseInt(Integer.java:580)在 java.lang.Integer.parseInt(Integer.java:615)在 set07102.Cards.main(Cards.java:68)C:\Users\qasim\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53:Java 返回:1

意思是:

出现错误.我们尽力为您提供尽可能多的信息这是主线程中的异常.它被称为 NumberFormatException 并且在输入Ace of Clubs"时发生.在 NumberFormatException.java 的第 65 行,这是一个构造函数,它是从 Integer.parseInt() 调用的,它位于文件 Integer.java 中的第 580 行,它是从 Integer.parseInt() 调用的,它位于文件 Integer.java 中的第 615 行,它是从第 68 行 Cards.java 文件中的 main 方法调用的.它导致退出代码 1

换句话说,您尝试将 "Ace of Clubs" 解析为 int,这是 Java 无法使用 Integer.parseInt.Java 提供了漂亮的堆栈跟踪,它可以准确地告诉您问题是什么.您正在寻找的工具是调试器,使用断点可以让您在所选时刻检查应用程序的状态.

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

if (cards[index].startsWith("Ace"))值 = 1;else if (cards[index].startsWith("King"))值 = 12;否则 if (cards[index].startsWith("Queen"))值 = 11;...别的 {尝试 {Integer.parseInt(string.substring(0,cards[index].indexOf("")));} catch (NumberFormatException e){//出了些问题}}

Java 中的 Exception 是什么?

<块引用>

异常是一个事件,它在执行一个程序,打乱了程序指令的正常流程.

-文档

Integer#parseInt

中的构造函数和用法

static NumberFormatException forInputString(String s) {return new NumberFormatException("对于输入字符串:\"" + s + "\"");}公共 NumberFormatException (String s) {超级(s);}

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

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

或更高版本,如果输入 String s 的格式不可解析:

throw NumberFormatException.forInputString(s);

什么是NumberFormatException?

<块引用>

抛出表示应用程序已尝试将字符串转换为数字类型之一,但该字符串没有适当的格式.

-文档

NumberFormatException extends IllegalArgumentException.它告诉我们它是更特殊的IllegalArgumentException.事实上,它用于强调虽然参数类型是正确的(String),但 String 的内容不是数字(a,b,c,d,e,f 被认为是 HEX 中的数字,在需要时是合法的).

我该如何解决?
好吧,不要解决它被抛出的事实.扔了就好了.您需要考虑以下几点:

  1. 我可以阅读堆栈跟踪吗?
  2. 导致 ExceptionStringnull 吗?
  3. 它看起来像一个数字吗?
  4. 是我的字符串"还是用户的输入?
  5. 待续

广告.1.

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

广告.2.

当你看到,代替 "For input string:" 和输入,有一个 null (not "null") 这意味着,您试图将空引用传递给一个数字.如果您真的想将 is 视为 0 或任何其他数字,您可能会对我在 StackOverflow 上的另一篇文章感兴趣.可在此处获得.

解决意外 null 的描述在 StackOverflow 线程中有很好的描述什么是 NullPointerException我该如何解决?.

广告.3.

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

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

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

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

广告.4.

最后我们达成共识,我们无法避免用户输入abc"作为数字字符串的情况.为什么?因为他可以.幸运的是,那是因为他是一名测试人员,或者只是一个极客.最坏的情况是攻击者.

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

尝试{i = Integer.parseInt(myString);} catch (NumberFormatException e) {e.printStackTrace();//以某种方式解决输入不正确的问题.这取决于您的业务逻辑.}

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)

My While Loop:

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

解决方案

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

means:

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

In other words, you tried to parse "Ace of Clubs" to an int what Java can't do with method Integer.parseInt. Java has provided beautiful stacktrace which tells you exactly what the problem is. The tool you're looking for is debugger and using breakpoints will allow you to inspect the state of you application at the chosen moment.

The solution might be the following logic in case you want to use parsing:

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
    }
}

What is an Exception in Java?

An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.

-Documentation

Constructors and usage in Integer#parseInt

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

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

They are important for understanding how to read the stacktrace. Look how the NumberFormatException is thrown from Integer#parseInt:

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

or later if the format of the input String s is not parsable:

throw NumberFormatException.forInputString(s); 

What is a NumberFormatException?

Thrown to indicate that the application has attempted to convert a string to one of the numeric types, but that the string does not have the appropriate format.

-Documentation

NumberFormatException extends IllegalArgumentException. It tells us that it's more specialized IllegalArgumentException. Indeed, it's used for highlighting that although, the argument type was correct (String) the content of the String wasn't numeric (a,b,c,d,e,f are considered digits in HEX and are legal when needed).

How do I fix it?
Well, don't fix the fact that it's thrown. It's good that it's thrown. There are some things you need to consider:

  1. Can I read the stacktrace?
  2. Is the String which causes an Exception a null?
  3. Does it look like a number?
  4. Is it 'my string' or user's input?
  5. to be continued

Ad. 1.

The first line of a message is an information that the Exception occurred and the input String which caused the problem. The String always follows : and is quoted ("some text"). Then you become interested in reading the stacktrace from the end, as the first few lines are usually NumberFormatException's constructor, parsing method etc. Then at the end, there is your method in which you made a bug. It will be pointed out in which file it was called and in which method. Even a line will be attached. You'll see. The example of how to read the stacktrace is above.

Ad. 2.

When you see, that instead of "For input string:" and the input, there is a null (not "null") it means, that you tried to pass the null reference to a number. If you actually want to treat is as 0 or any other number, you might be interested in my another post on StackOverflow. It's available here.

The description of solving unexpected nulls is well described on StackOverflow thread What is a NullPointerException and how can I fix it?.

Ad. 3.

If the String that follows the : and is quoted looks like a number in your opinion, there might be a character which your system don't decode or an unseen white space. Obviously " 6" can't be parsed as well as "123 " can't. It's because of the spaces. But it can occure, that the String will look like "6" but actually it's length will be larger than the number of digits you can see.

In this case I suggest using the debugger or at least System.out.println and print the length of the String you're trying to parse. If it shows more than the number of digits, try passing stringToParse.trim() to the parsing method. If it won't work, copy the whole string after the : and decode it using online decoder. It'll give you codes of all characters.

There is also one case which I have found recently on StackOverflow, that you might see, that the input looks like a number e.g. "1.86" and it only contains those 4 characters but the error still exists. Remember, one can only parse integers with #Integer#parseInt#. For parsing decimal numbers, one should use Double#parseDouble.

Another situation is, when the number has many digits. It might be, that it's too large or too small to fit int or long. You might want to try new BigDecimal(<str>).

Ad. 4.

Finally we come to the place in which we agree, that we can't avoid situations when it's user typing "abc" as a numeric string. Why? Because he can. In a lucky case, it's because he's a tester or simply a geek. In a bad case it's the attacker.

What can I do now? Well, Java gives us try-catch you can do the following:

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.
}

这篇关于什么是 NumberFormatException 以及如何修复它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆