Qu'est-ce qu'une exception NumberFormatException et comment puis-je la réparer?


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)

Ma boucle 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
Author: xenteros, 2016-10-04

9 answers

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

Signifie:

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

En d'autres termes, vous avez essayé d'analyser "Ace of Clubs" en int ce que Java ne peut pas faire avec la méthode Integer.parseInt. Java a fourni une belle stacktrace qui vous indique exactement quel est le problème. L'outil que vous recherchez est débogueur et à l'aide de , les points d'arrêt va vous permettre d'inspecter les état de la demande à l'instant.

La solution pourrait être la logique suivante si vous souhaitez utiliser analyse:

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

Qu'est Ce qu'un Exception en Java?

Une exception est un événement qui se produit pendant l'exécution d'une programme, qui perturbe le flux normal des instructions du programme.

-Documentation

Constructeurs et utilisation dans Integer#parseInt

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

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

Ils sont importants pour comprendre comment lire la stacktrace. Regardez comment le NumberFormatException est jeté à partir de Integer#parseInt:

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

Ou plus tard si le le format de l'entrée String s n'est pas analysée:

throw NumberFormatException.forInputString(s); 

Qu'est Ce qu'un NumberFormatException?

Lancé pour indiquer que l'application a tenté de convertir une chaîne en l'un des types numériques, mais que la chaîne n'a pas le format approprié.

-Documentation

NumberFormatException extends IllegalArgumentException. Il nous dit qu'il est plus spécialisé IllegalArgumentException. En effet, il est utilisé pour mettre en évidence que bien que, le type d'argument était correct (String) le le contenu du Stringn'était pas numérique ( a,b,c,d,e,f sont considérés comme des chiffres en hexadécimal et sont légaux en cas de besoin).

Comment puis-je le réparer?
Eh bien, ne répare pas le fait qu'il est jeté. C'est bien qu'il est lancé. Il y a certaines choses que vous devez considérer:

  1. Puis-je lire le stacktrace?
  2. Est le String, qui provoque une Exception un null?
  3. Ressemble-t-il à un nombre?
  4. Est-ce "ma chaîne" ou celle de l'utilisateur d'entrée?
  5. pour être poursuivi

Ad. 1.

La première ligne d'un message est une information indiquant que l'exception s'est produite et l'entrée String qui a causé le problème. La chaîne suit toujours : et est entre guillemets ("some text"). Ensuite, vous vous intéressez à la lecture de la stacktrace à partir de la fin, car les premières lignes sont généralement le constructeur de NumberFormatException, la méthode d'analyse, etc. Puis à la fin, il y est votre méthode dans laquelle vous avez fait un bug. Il sera souligné dans quel fichier il a été appelé et dans quelle méthode. Même une ligne sera attachée. Vous le verrez. L'exemple de la façon de lire la stacktrace est ci-dessus.

Ad. 2.

Quand vous voyez, qu'au lieu de "For input string:" et l'entrée, il y a un null (pas "null") cela signifie que vous avez essayé de passer la référence null à un nombre. Si vous voulez réellement traiter est comme 0 ou tout autre nombre, vous pourriez être intéressé par mon autre post sur StackOverflow. Il est disponible ici.

La description de la résolution de nulls inattendus est bien décrite sur le thread StackOverflowQu'est-ce qu'une NullPointerException et comment puis-je la réparer?.

Ad. 3.

Si le String qui suit le : et est cité ressemble à un nombre à votre avis, il peut y avoir un caractère que votre système ne décodera pas ou un espace blanc invisible. Évidemment, " 6" ne peut pas être analysé aussi bien que "123 " ne peut pas. C'est à cause du espace. Mais il peut arriver que le String ressemble à "6" mais en fait sa longueur sera plus grande que le nombre de chiffres que vous pouvez voir.

Dans ce cas, je suggère d'utiliser le débogueur ou au moins System.out.println et d'imprimer la longueur du String que vous essayez d'analyser. S'il affiche plus que le nombre de chiffres, essayez de passer stringToParse.trim() à la méthode d'analyse. Si cela ne fonctionne pas, copiez la chaîne entière après le : et décodez-la à l'aide du décodeur en ligne. Il vous donnera des codes de tous caractère.

Il y a aussi un cas que j'ai trouvé récemment sur StackOverflow, que vous pourriez voir, que l'entrée ressemble à un nombre par exemple "1.86" et qu'elle ne contient que ces 4 caractères mais l'erreur existe toujours. Rappelez-vous, on ne peut analyser que des entiers avec #Integer#parseInt#. Pour analyser les nombres décimaux, il faut utiliser Double#parseDouble.

Une autre situation est, lorsque le nombre a plusieurs chiffres. Il se peut qu'il soit trop grand ou trop petit pour tenir int ou long. Vous voudrez peut-être essayer new BigDecimal(<str>).

Ad. 4.

Enfin, nous arrivons à l'endroit où nous sommes d'accord, que nous ne pouvons pas éviter les situations où l'utilisateur tape "abc" comme une chaîne numérique. Pourquoi? Parce qu'il peut. Dans un cas chanceux, c'est parce qu'il est un testeur ou simplement un geek. Dans un mauvais cas, c'est l'attaquant.

Que puis-je faire maintenant? Eh bien, Java nous donne try-catch vous pouvez faire ce qui suit:

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.
}
 34
Author: xenteros, 2018-04-23 19:12:32

Qu'est Ce qu'un NumberFormatException?

Cette exception est levée pour indiquer que l'application a tenté de convertir un string à l'un des types numériques, mais que le string n'a pas le format approprié.

Dans votre cas, selon votre trace de pile, cette exception a été levée par Integer.parseInt(String) ce qui signifie que le String fourni ne contient pas de integer analysable. Et toujours selon la trace de la pile, cela est dû au fait que vous avez essayé d'analyser l'String "As de trèfle" comme un entier qui ne peut pas fonctionner car il n'est pas le String représentation d'un entier.

Comment le réparer?

, Le plus simple et le générique façon est d'attraper l'exception NumberFormatException

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

Cela fonctionnera mais attraper une exception est lent car il doit construire la pile d'appels pour créer le Exception qui est coûteux, donc si vous pouvez l'éviter, faites-le. De plus vous devrez gérer correctement l'exception ce qui n'est pas toujours le cas évident.

, Ou vous pouvez utiliser un regular expression pour vérifier d'abord si l'String matches avec un Integer, mais il est tout à fait enclins à faire des erreurs que vous pouvez facilement utiliser un mauvais regular expression.


Dans votre cas, une approche plus OO devrait être utilisée au lieu de traiter String, par exemple, vous pouvez utiliser un class ou un enum pour représenter vos cartes au lieu d'utiliser un simple String car il est beaucoup plus sujet aux erreurs comme vous l'avez déjà remarqué.

Donc, si vous décidez d'utiliser un dédié classe de votre carte, votre code pourrait être:

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

Pour la couleur et le rang d'une carte, nous pouvons utiliser un enum car il y a des quantités limitées de rangs et de costumes existants.

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
}

, Puis cards serait un tableau de Card au lieu d'un tableau de String, et pourrait être initialisé suivante:

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

Si vous avez besoin de mélanger votre tableau de cartes, vous pouvez procéder comme suivant (veuillez noter que si vous décidez d'utiliser un List de cartes au lieu de simplement utiliser un tableau Collections.shuffle(list))

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

Vous pourrez alors accéder directement à la valeur de votre carte avec cards[index].getRank().getValue() sans prendre le risque d'obtenir une exception (sauf un IndexOutOfBoundsException si vous n'utilisez pas un index approprié).

 9
Author: Nicolas Filotto, 2016-10-13 08:14:26

Ressemble à cards[]est Chaîne tableau et vous essayez de convertir Ace of Clubsen Entier.

int first_value = Integer.parseInt(cards[index]);
 6
Author: Vivek G, 2016-10-04 10:37:44
java.lang.NumberFormatException 

Se produit lorsque vous essayez d'analyser une entrée qui n'est pas une chaîne numérique.

Dans votre cas, vous essayez d'analyser une chaîne (qui n'a pas de nombre )comme entier. Comme il n'est pas possible L'exception NumberFormatException s'est produite.

int first_value = Integer.parseInt(cards[index]);//cards[index] value should be //number string "123" not "abc"
 2
Author: Rajesh Gopu, 2016-10-19 07:38:55

Une exception NumberFormatException est la façon dont Java doit vous dire "J'ai essayé de convertir une chaîne en int et je ne pouvais pas le faire".

Dans votre trace d'exception, vous pouvez lire

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)

Fondamentalement, cela signifie que, à la ligne 68 de votre code, vous appelez à l'Entier.Méthode parseInt passant "As des clubs" comme paremeter. Cette méthode attend une valeur entière représentée sous forme de chaîne, par exemple "4" , donc la méthode se plaint de lancer une exception NumberFormatException car "Ace of Clubs" ne semble pas un entier à tout.

 2
Author: jmlotero, 2016-10-19 09:06:07

La toute première chose qui m'a jeté pour une boucle (sans jeu de mots) était que vous limitiez la valeur à 1-13 quand elle doit être 0-52. Aussi avec votre logique, la valeur était toujours plus élevée. Une meilleure approche est avec un générateur de nombre. Voici mon code utilisant un générateur de nombres (ou 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++;
}
}

Quant à l'exception NumberFormatException, je crois que Nicolas Filotto a fait du bon travail pour expliquer cela.

 1
Author: thekodester, 2016-10-18 11:10:33

A NumberFormatException signifie que Integer.parseInt() ne pouvait pas traduire la chaîne en un nombre.

Je suggère l'une des deux options suivantes:

  1. Encapsuler les cartes sous forme de combo nom(chaîne)/valeur(int). Utilisez la valeur pour effectuer des comparaisons et le nom pour présenter des informations à l'utilisateur. Cards[] devient alors une liste de cartes, pas de chaînes.

  2. Analysez les chaînes vous-même. Ce qui peut être plus facile, puisque vous l'avez déjà fait avec les bits if(cards[index].startsWith("Ace")) { value = 1; }. Vous pouvez les déplacer dans une fonction appelée CardToInt() (ou quoi que ce soit), et utiliser cette fonction au lieu de Integer.parseInt().

 1
Author: Andrew Tofelt, 2016-10-18 20:59:58
int first_value = Integer.parseInt(cards[index]); 

En écrivant la déclaration ci-dessus, vous essayez d'analyser "As of Clubs" en tant que nombre.

Vous pouvez utiliser la méthode suivante pour tester si une chaîne peut être analysée en entier:

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

En ce qui concerne votre question, qu'est-ce que NumberFormatException : Il est lancé pour indiquer que l'application a tenté de convertir une chaîne en l'un des types numériques, mais que la chaîne n'a pas le format approprié. (réf - http://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html )

 1
Author: roopaliv, 2016-10-19 07:46:00

L'exception vient dans votre code, où vous convertissez la chaîne en entier:

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

Où vous passez une chaîne comme "As de clubs" qui n'est pas possible de convertir en entier,donc il lève une exception de format numérique. Vous pouvez utiliser,

try {
     ....
     // Your Code
     ....
    }
catch(NumberFormatException e)
{
    e.getMessage();  //You can use anyone like printStackTrace() ,getMessage() to handle the Exception
}
 0
Author: Anands23, 2016-10-18 11:29:59