wake-up-neo.com

Was ist eine NumberFormatException und wie kann ich sie beheben?

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)

Meine While-Schleife:

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
17
Qasim Imtiaz
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

meint:

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

Mit anderen Worten, Sie haben versucht, "Ace of Clubs" in ein int zu parsen, das Java mit der Methode Integer.parseInt nicht verwenden kann. Java hat einen schönen Stacktrace zur Verfügung gestellt, der Ihnen genau sagt, was das Problem ist. Das Werkzeug, nach dem Sie suchen, ist debugger. Wenn Sie breakpoints verwenden, können Sie den state Ihrer Anwendung zum ausgewählten Zeitpunkt überprüfen.

Die Lösung könnte die folgende Logik sein, falls Sie Parsing verwenden möchten:

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

Was ist ein Exception in Java?

Eine Ausnahme ist ein Ereignis, das während der Ausführung eines .__ auftritt. Programm, das den normalen Fluss der Programmanweisungen unterbricht.

- Dokumentation

Konstruktoren und Verwendung in Integer#parseInt

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

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

Sie sind wichtig, um zu verstehen, wie der Stacktrace gelesen wird. Sehen Sie, wie die NumberFormatException von Integer#parseInt geworfen wird:

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

oder später, wenn das Format der Eingabe String s nicht analysierbar ist:

throw NumberFormatException.forInputString(s); 

Was ist eine NumberFormatException?

Wird ausgelöst, um anzuzeigen, dass die Anwendung versucht hat, eine Zeichenfolge in einen der numerischen Typen zu konvertieren, die Zeichenfolge jedoch nicht das entsprechende Format hat.

- Dokumentation

NumberFormatExceptionextendsIllegalArgumentException. Es sagt uns, dass es mehr IllegalArgumentException ist. Es wird in der Tat verwendet, um hervorzuheben, dass der Argumenttyp zwar korrekt war (String), der Inhalt von String jedoch nicht numerisch war (a, b, c, d, e, f gelten als Ziffern in HEX und sind zulässig, wenn erforderlich).

Wie kann ich das Problem beheben?
Nun gut, nicht die Tatsache, dass es geworfen wird. Es ist gut, dass es geworfen wird. Es gibt einige Dinge, die Sie beachten sollten:

  1. Kann ich den Stacktrace lesen?
  2. Ist das String, das ein Exception verursacht, ein null?
  3. Sieht es aus wie eine Zahl?
  4. Ist es 'meine Zeichenfolge' oder eine Benutzereingabe?
  5. Fortsetzung folgt

Anzeige. 1.

Die erste Zeile einer Nachricht enthält Informationen darüber, dass die Ausnahme aufgetreten ist, und die Eingabe String, die das Problem verursacht hat. Der String folgt immer : und wird in Anführungszeichen gesetzt ("some text"). Dann interessieren Sie sich für das Lesen des Stacktraces vom Ende, da die ersten Zeilen normalerweise der Konstruktor, die Parsing-Methode von NumberFormatException usw. sind. Am Ende gibt es Ihre Methode, in der Sie einen Fehler gemacht haben. Es wird darauf hingewiesen, in welcher Datei es aufgerufen wurde und in welcher Methode. Sogar eine Zeile wird angehängt. Du wirst sehen. Das Beispiel für das Lesen des Stacktraces finden Sie oben.

Anzeige. 2.

Wenn Sie sehen, dass anstelle von "For input string:" und der Eingabe ein null (nicht "null") vorhanden ist, bedeutet dies, dass Sie versucht haben, die Nullreferenz an eine Zahl zu übergeben. Wenn Sie eigentlich als 0 oder eine andere Zahl behandeln möchten, interessieren Sie sich möglicherweise für meinen anderen Beitrag in StackOverflow. Es ist hier verfügbar.

Die Beschreibung zum Lösen unerwarteter nulls ist im StackOverflow-Thread Was ist eine NullPointerException und wie kann ich sie beheben? Gut beschrieben. 

Anzeige. 3.

Wenn das String, das dem : folgt und in Anführungszeichen steht, Ihrer Meinung nach wie eine Zahl aussieht, könnte es ein Zeichen geben, das Ihr System nicht decodiert, oder ein unsichtbarer Leerraum. Natürlich kann " 6" nicht so gut analysiert werden wie "123 " nicht. Es ist wegen der Räume. Es kann jedoch vorkommen, dass String wie "6" aussieht, aber tatsächlich ist die Länge größer als die Anzahl der angezeigten Ziffern.

In diesem Fall empfehle ich, debugger oder zumindest System.out.println zu verwenden und die Länge des String zu drucken, das Sie analysieren möchten. Wenn mehr als die Anzahl der Ziffern angezeigt wird, übergeben Sie stringToParse.trim() an die Parsing-Methode. Wenn dies nicht funktioniert, kopieren Sie die gesamte Zeichenfolge nach dem : und dekodieren Sie sie mit einem Online-Decoder. Sie erhalten Codes aller Zeichen.

Es gibt auch einen Fall, den ich kürzlich in StackOverflow gefunden habe, und Sie könnten sehen, dass die Eingabe wie eine Zahl aussieht, z. "1.86" und enthält nur diese 4 Zeichen, aber der Fehler ist noch vorhanden. Denken Sie daran, dass Sie Ganzzahlen nur mit # Integer # parseInt # analysieren können. Für die Analyse von Dezimalzahlen sollte Double#parseDouble verwendet werden.

Eine andere Situation ist, wenn die Nummer viele Ziffern hat. Es kann sein, dass es zu groß oder zu klein ist, um int oder long zu passen. Möglicherweise möchten Sie new BigDecimal(<str>) ausprobieren.

Anzeige. 4.

Schließlich kommen wir zu dem Punkt, an dem wir uns einig sind, dass wir Situationen nicht vermeiden können, wenn der Benutzer "abc" als numerische Zeichenfolge eingibt. Warum? Weil er es kann. In einem glücklichen Fall ist es, weil er ein Tester oder einfach nur ein Geek ist. Im schlimmen Fall ist es der Angreifer.

Was kann ich jetzt tun? Nun, Java gibt uns try-catch Sie können Folgendes tun:

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

Was ist eine NumberFormatException?

Diese Ausnahme wird ausgelöst, um anzuzeigen, dass die Anwendung über .__ verfügt. Es wurde versucht, ein string-Objekt in einen der numerischen Typen zu konvertieren. string hat nicht das passende Format.

In Ihrem Fall wurde diese Ausnahme gemäß Ihrer Stack-Ablaufverfolgung von Integer.parseInt(String) ausgelöst, was bedeutet, dass das bereitgestellte String kein analysierbares integer enthält. Laut Stack-Trace ist es immer noch der Tatsache geschuldet, dass Sie versucht haben, das String "Ass of Clubs" als Ganzzahl zu analysieren, die nicht funktionieren kann, da es nicht die String-Darstellung einer Ganzzahl ist.

Wie man es repariert?

Der einfachste und allgemeinste Weg ist, die Ausnahme NumberFormatException abzufangen.

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

Es funktioniert zwar, aber das Erfassen einer Ausnahme ist langsam, da der Aufrufstapel erstellt werden muss, um Exception zu erstellen, was teuer ist. Wenn Sie dies vermeiden können, tun Sie dies. Außerdem müssen Sie die Ausnahme ordnungsgemäß verwalten, was nicht immer offensichtlich ist.

Oder Sie könnten einen regular expression verwenden, um zuerst zu prüfen, ob Stringmatches mit einem Integer ist, aber es ist sehr fehleranfällig, da Sie leicht einen falschen regular expression verwenden können.


In Ihrem Fall sollte anstelle von String ein weiterer OO -Ansatz verwendet werden. Beispielsweise können Sie class oder enum anstelle von einfachen String zur Darstellung Ihrer Karten verwenden, da dies viel mehr Fehler verursacht, als Sie dies tun schon bemerkt 

Wenn Sie sich also entscheiden, eine dedizierte Klasse für Ihre Karte zu verwenden, könnte Ihr Code folgendermaßen lauten:

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

Für die Farbe und den Rang einer Karte können wir enum verwenden, da die Anzahl der vorhandenen Ränge und Anzüge begrenzt ist.

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
}

Dann wäre cards ein Array von Card anstelle eines Arrays von String und könnte als nächstes initialisiert werden:

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]);
    }
}

Wenn Sie Ihr Kartenarray neu mischen müssen, können Sie als nächstes vorgehen (beachten Sie, dass Sie bei Verwendung eines List-Karten anstelle eines Arrays einfach Collections.shuffle(list) verwenden.)

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

Dann können Sie mit cards[index].getRank().getValue() direkt auf den Wert Ihrer Karte zugreifen, ohne das Risiko einzugehen, eine Ausnahme zu erhalten (außer IndexOutOfBoundsException, wenn Sie keinen geeigneten Index verwenden).

9
Nicolas Filotto

Sieht aus wie cards[] String array und Sie versuchen, Ace of Clubs in Integer zu konvertieren.

int first_value = Integer.parseInt(cards[index]);
6
Vivek G
Java.lang.NumberFormatException 

tritt auf, wenn Sie versuchen, Eingaben zu analysieren, die keine Zahlenzeichenfolge sind.

In Ihrem Fall versuchen Sie, einen String (der keine Nummer hat) als Integer ..__ zu parsen, da dies nicht möglich ist.

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

Eine NumberFormatException ist die Art, wie Java Sie sagen muss: "Ich habe versucht, einen String in int zu konvertieren und konnte es nicht.".

In Ihrer Ausnahmespur können Sie lesen

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)

Im Grunde bedeutet dies, dass Sie in der Zeile 68 Ihres Codes die Methode Integer.parseInt aufrufen und "Ace of Clubs" als Paremeter übergeben. Diese Methode erwartet einen ganzzahligen Wert, der als String dargestellt wird, z. "4", so beschwert sich die Methode, eine NumberFormatException zu werfen, da "Ace of Clubs" überhaupt keine ganze Zahl zu sein scheint.

2
jmlotero

Das allererste, was mich für eine Schleife warf (kein Wortspiel beabsichtigt) war, dass Sie den Wert auf 1-13 begrenzt haben, wenn er 0-52 sein muss. Auch mit Ihrer Logik war der Wert immer höher. Ein besserer Ansatz ist ein Zahlengenerator. Hier ist mein Code mit einem Zahlengenerator (oder 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++;
}
}

In Bezug auf die NumberFormatException glaube ich, dass Nicolas Filotto das gut erklärt hat.

1
thekodester

Eine NumberFormatException bedeutet, dass Integer.parseInt() die Zeichenfolge nicht in eine Zahl übersetzen konnte.

Ich würde eine von zwei Möglichkeiten vorschlagen:

  1. Verkapseln Sie Karten als Kombination aus Name (String)/Wert (Int). Verwenden Sie den Wert für Vergleiche und den Namen, um dem Benutzer Informationen anzuzeigen. Cards[] wird dann zu einer Liste von Karten, nicht zu Zeichenfolgen.

  2. Analysieren Sie die Zeichenfolgen selbst. Was möglicherweise einfacher ist, da Sie es bereits mit den if(cards[index].startsWith("Ace")) { value = 1; }-Bits gemacht haben. Sie können diese in eine Funktion namens CardToInt() (oder was auch immer) verschieben und diese Funktion anstelle von Integer.parseInt() verwenden.

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

während Sie die obige Aussage schreiben, versuchen Sie "Ace of Clubs" als Zahl zu analysieren. 

sie können die folgende Methode verwenden, um zu testen, ob eine Zeichenfolge als Ganzzahl analysiert werden kann:

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

In Bezug auf Ihre Frage, was ist NumberFormatException: Es wird ausgelöst, um anzuzeigen, dass die Anwendung versucht hat, eine Zeichenfolge in einen der numerischen Typen zu konvertieren, die Zeichenfolge jedoch nicht das entsprechende Format hat. (ref - http://docs.Oracle.com/javase/7/docs/api/Java/lang/NumberFormatException.html )

1
roopaliv

Die Ausnahme ist in Ihrem Code enthalten, in dem Sie den String in eine Ganzzahl konvertieren:

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

wenn Sie einen String als "Ace of Clubs" übergeben, der nicht als Ganzzahl konvertiert werden kann, löst er die Number-Format-Ausnahme aus. Sie können verwenden,

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