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


评论

int first_value = Integer.parseInt(cards [index]); -您尝试将字符串解析为int,但字符串为“ Ace of Clubs”。

您缺少卡片... King是13,Queen是12,Jack是11,只是说;)您应该使用其他方法,因为您不能拥有以King和3开头的卡片。为什么要使用索引限制为52?您没有使用颜色。最后,如果您尝试q,您将在结束之前收到无效的答案消息。对于错误,一切都可以说。

#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.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提供了漂亮的stacktrace,它可以告诉您确切的问题是什么。您正在寻找的工具是调试器,使用断点将使您能够在选定的时刻检查应用程序的状态。

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

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: />
String s是什么?


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


-文档

NumberFormatException NumberFormatException extends。它告诉我们它是更专业的IllegalArgumentException。确实,它用于突出显示尽管参数类型是正确的(IllegalArgumentException),但String的内容不是数字(a,b,c,d,e,f被视为十六进制数字,并且在需要时是合法的)。

我该如何解决?
好,不要解决它被抛出的事实。扔了很好。您需要考虑一些事情:


我可以阅读堆栈跟踪信息吗?
String导致StringException吗?
它看起来像数字?
是“我的字符串”还是用户输入的内容?
要继续吗?

广告。 1.

消息的第一行是发生异常的信息以及引起问题的输入null。字符串始终跟随String并用引号(:)表示。然后您开始对从头开始阅读stacktrace感兴趣,因为前几行通常是"some text"的构造函数,解析方法等。最后,您的方法中就有一个bug。将会指出在哪个文件中调用了哪个方法。甚至连一条线。你会看到的。以上是如何读取stacktrace的示例。

Ad。 2.

看到的是NumberFormatException(不是"For input string:"),而不是null和输入,这意味着您试图将空引用传递给数字。如果您实际上想将其视为0或任何其他数字,则可能对我在StackOverflow上的另一篇文章感兴趣。它可以在这里使用。

在StackOverflow线程上很好地描述了解决意外"null"的描述。什么是NullPointerException,我该如何解决?

广告。 3.

如果您认为null之后的String看起来像是一个数字,则可能是系统无法解码的字符或空白。显然,无法解析:以及无法解析。这是因为空间。但是可能会出现," 6"看起来像"123 ",但实际上它的长度会大于您看到的位数。

这种情况下,我建议使用调试器或至少使用String并打印您要解析的"6"的长度。如果显示的位数超过位数,请尝试将System.out.println传递给解析方法。如果不起作用,请在String之后复制整个字符串,然后使用在线解码器对其进行解码。它会为您提供所有字符的代码。

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

另一种情况是,该数字有很多数字。可能太大或太小而无法容纳"1.86"Double#parseDouble。您可能需要尝试int

广告。 4.

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

我现在该怎么办?好吧,Java为我们提供了long,您可以执行以下操作:

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


评论


“黑桃王牌” ???另外,在描述性错误详细信息中,我认为您有第二个Integer.parseInt的行号(615到580)有错字。

– Abhineet
16-10-12在11:51

有时间的时候,我会把重点放在第5点的数字上。

– xenteros
16-10-13在7:07

一个漂亮的答案。我认为我应该更经常地接近这个问题;-)

–GhostCat
17年2月2日在10:56

@GhostCat这就是为什么我准备了这个答案

– xenteros
17年12月2日在11:05

@ OleV.V。当然!更新

– xenteros
18年4月23日在19:12

#2 楼

什么是NumberFormatException


引发此异常,表明应用程序已尝试将string转换为数字类型之一,但是
string没有适当的格式。



根据您的堆栈跟踪,此异常由Integer.parseInt(String)引发,这意味着所提供的String不包含可解析的integer。仍然根据堆栈跟踪,这是由于您试图将String“ Ace of Clubs”解析为一个整数而无法工作的事实,因为它不是整数的String表示形式。

如何解决?

最简单,通用的方法是捕获异常NumberFormatException

int value = -1;
try {
    value = Integer.parseInt(myString);
} catch (NumberFormatException e) {
    // The format was incorrect
}


可以,但是捕获异常是速度很慢,因为它需要构建调用堆栈来创建Exception,这非常昂贵,因此,如果可以避免的话,可以这样做。此外,您将需要适当地管理并不总是很明显的异常。

或者您可以使用regular expression首先检查Stringmatches是否带有Integer,但是它很容易出错,因为您可以轻松使用错误的regular expression


在您的情况下,应使用更多面向对象的方法代替处理String,例如,您可以使用classenum代表您的卡,而不是使用简单的String,因为您已经注意到它更容易出错。

因此,如果您决定对卡使用专用的类别,则代码可能是:

public class Card {

    private final Rank rank;
    private final Suit suit;

    public Card(final Rank rank, final Suit suit) {
        this.rank = rank;
        this.suit = suit;
    }

    public Rank getRank() {
        return this.rank;
    }

    public Suit getSuit() {
        return this.suit;
    }
}


一张卡片,我们可以使用enum,因为现有的等级和西服数量有限。

public enum Rank {
    ACE(1), TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6), SEVEN(7), HEIGHT(8),
    NINE(9), TEN(10), JACK(11), QUEEN(12), KING(13);

    private final int value;

    Rank(final int value) {
        this.value = value;
    }

    public int getValue() {
        return this.value;
    }
}

public enum Suit {
    SPADE, HEART, DIAMOND, CLUB
}


然后cards将是Card的数组而不是String的数组,并且可以初始化为下一个:

Rank[] ranks = Rank.values();
Suit[] suits = Suit.values();
Card[] cards = new Card[ranks.length * suits.length];
for (int i = 0; i < ranks.length; i++) {
    for (int j = 0; j < suits.length; j++) {
        cards[i * suits.length + j] = new Card(ranks[i], suits[j]);
    }
}


如果您需要洗牌阵列,则可以继续进行下一个操作(请注意,如果您决定使用List卡而不是阵列,只需使用Collections.shuffle(list)

List<Card> allCards = Arrays.asList(cards);
Collections.shuffle(allCards);
allCards.toArray(cards);


然后,您将可以通过cards[index].getRank().getValue()直接访问您的卡的价值,而不必冒险遇到异常(如果您使用的索引不正确,则IndexOutOfBoundsException除外)。

评论


我不会同意您的观点,即抓住NFE很难看。在大型系统中,您可以假设用户将提供非数字输入,另一方面,您希望保持日志整洁,最好是捕获它并记录信息或抛出自己的服务异常,而不是让整个堆栈跟踪以红色打印。

– xenteros
16-10-13在7:59

通常,@ xenteros捕获异常的速度很慢,因为它需要构建调用堆栈来创建昂贵的Exception,因此,如果可以避免这样做,但有时却无法避免。在这里,您可以通过使用真正的面向对象方法来避免这种情况,这是我建议的

–尼古拉斯·菲洛托(Nicolas Filotto)
16-10-13在8:08

#3 楼

看起来cards[]是字符串数组,您正尝试将Ace of Clubs转换为Integer。

int first_value = Integer.parseInt(cards[index]);


#4 楼

java.lang.NumberFormatException 


发生在您尝试解析某些非数字字符串的输入时。

在您的情况下,您尝试将字符串(不具有number)解析为Integer。
由于不可能
发生NumberFormatException异常。

int first_value = Integer.parseInt(cards[index]);//cards[index] value should be //number string "123" not "abc"


#5 楼

Java必须说NumberNumberException是“我试图将String转换为int而我做不到”。

在异常跟踪中,您可以阅读

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)


基本上,这意味着您在代码的第68行中调用Integer.parseInt方法,并将“ Ace of Clubs”作为参数来调用。此方法需要一个以String表示的整数值,例如“ 4”,因此方法抱怨抛出NumberFormatException,因为“ Ace of Clubs”似乎根本不是整数。

#6 楼

NumberFormatException意味着Integer.parseInt()无法将字符串转换为数字。

我建议使用以下两个选项之一:


将卡封装为名称(字符串)/ value(int)组合。使用该值进行比较,并使用名称向用户显示信息。然后,Cards[]成为卡列表,而不是字符串。
自己解析字符串。这可能会更容易,因为您已经使用if(cards[index].startsWith("Ace")) { value = 1; }位完成了此操作。您可以将其移至名为CardToInt()(或其他函数)的函数中,然后使用该函数代替Integer.parseInt()


#7 楼

使我陷入循环(无双关语)的第一件事是,当值需要为0-52时,您将值限制为1-13。同样根据您的逻辑,该值始终更高。更好的方法是使用数字生成器。这是我使用数字生成器(或Java Random)的代码:

public static void main(String[] args) {

String[] cards = { "Ace of Clubs", "1 of Clubs", "2 of Clubs",
        "3 of Clubs", "4 of Clubs", "5 of Clubs", "6 of Clubs",
        "7 of Clubs", "8 of Clubs", "9 of Clubs", "10 of Clubs",
        "Queen of Clubs", "King of Clubs", "Ace of Diamonds",
        "1 of Diamonds", "2 of Diamonds", "3 of Diamonds",
        "4 of Diamonds", "5 of Diamonds", "6 of Diamonds",
        "7 of Diamonds", "8 of Diamonds", "9 of Diamonds",
        "10 of Diamonds", "Queen of Diamonds", "King of Diamonds",
        "Ace of Hearts", "1 of Hearts", "2 of Hearts", "3 of Hearts",
        "4 of Hearts", "5 of Hearts", "6 of Hearts", "7 of Hearts",
        "8 of Hearts", "9 of Hearts", "10 of Hearts",
        "Queen of Hearts", "King of Hearts", "Ace of Spades",
        "1 of Spades", "2 of Spades", "3 of Spades", "4 of Spades",
        "5 of Spades", "6 of Spades", "7 of Spades", "8 of Spades",
        "9 of Spades", "10 of Spades", "Queen of Spades",
        "King of Spades" };

Scanner scanner = new Scanner(System.in);
Random rand = new Random();
String response = "";
int index = 0;
int value = 0;  
while (!response.equals("q") && index < 52) {

    // set next card value based on current set of cards in play
    if (cards[index].endsWith("Clubs")) {
        value = rand.nextInt(12);
    }
    if (cards[index].endsWith("Diamonds")) {
        value = rand.nextInt(12) + 13;
    }
    if (cards[index].endsWith("Hearts")) {
        value = rand.nextInt(12) + 26;
    }
    if (cards[index].endsWith("Spades")) {
        value = rand.nextInt(12) + 39;
    }

    // display card too user (NOTE: we use the random number not the index)
    System.out.println("Card is: " + cards[value]);

    // ask user what well the next card be
    System.out.println("Will the next card be higher or lower?, press q if you want to quit");
    response = scanner.nextLine();

    // display if user was right (NOTE: compared the random number to the current index)
    // ignore incorrect response and just continue
    if ((value > index && response.startsWith("h")) || (value < index && response.startsWith("l"))) {
        System.out.println("You answer was right, well done!");
    } else {
        System.out.println("You answer was wrong, try again!");
    }

    // continue loop
    index++;
}
}


至于NumberFormatException,我相信Nicolas Filotto很好地解释了这一点。

#8 楼

int first_value = Integer.parseInt(cards[index]); 


在编写上述声明时,您试图将“ Ace of Clubs”解析为数字。

您可以使用以下方法测试是否可以将任何字符串解析为Integer:

boolean tryParseInt(String value) {  
     try {  
         Integer.parseInt(value);  
         return true;  
      } catch (NumberFormatException e) {  
         return false;  
      }  
}


关于您的问题,什么是NumberFormatException:引发该错误以表明应用程序已尝试将字符串转换为数字类型之一,但是该字符串没有适当的格式。 (参考-http://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html)

#9 楼

异常出现在您的代码中,您将字符串转换为整数:

int first_value = Integer.parseInt(cards[index]);


其中将字符串作为“ Ace of Clubs”传递,无法转换作为整数,因此会引发数字格式异常。您可以使用,

try {
     ....
     // Your Code
     ....
    }
catch(NumberFormatException e)
{
    e.getMessage();  //You can use anyone like printStackTrace() ,getMessage() to handle the Exception
}