Подтвердить что ты не робот

Что такое исключение 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)

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
4b9b3361

Ответ 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 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
    }
}

Что такое Exception в Java?

Исключением является событие, которое происходит во время выполнения программы и нарушает нормальный поток программных инструкций.

- Документация

Конструкторы и использование в 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. Действительно, он использовался для выделения того, что, хотя тип аргумента был правильным (String), содержимое String не было числовым (a, b, c, d, e, f считаются цифрами в HEX и допустимы при необходимости).

Как мне это исправить?
Ну, не фиксируй тот факт, что его бросили. Хорошо, что его бросили. Есть несколько вещей, которые вы должны рассмотреть:

  1. Можно ли прочитать трассировку стека?
  2. Является ли String которая вызывает Exception null?
  3. Это похоже на число?
  4. Это "моя строка" или пользовательский ввод?
  5. продолжение следует

Объявление. 1.

Первая строка сообщения содержит информацию о том, что возникло исключение, и String ввода, которая вызвала проблему. Строка всегда следует : и заключена в кавычки ("some text"). Затем вас интересует чтение трассировки стека с конца, так как первые несколько строк - это обычно конструктор NumberFormatException, метод синтаксического анализа и т.д. Затем, в конце, есть ваш метод, в котором вы сделали ошибку. Будет указано, в каком файле он был вызван и в каком методе. Даже линия будет прикреплена. Вот увидишь. Пример того, как читать трассировку стека, приведен выше.

Объявление. 2.

Когда вы видите, что вместо "For input string:" и ввода есть null (не "null"), это означает, что вы пытались передать нулевую ссылку на число. Если вы действительно хотите обработать как 0 или любое другое число, вас может заинтересовать еще один мой пост на StackOverflow. Это доступно здесь.

Описание решения неожиданного null хорошо описано в потоке StackOverflow. Что такое исключение NullPointerException и как я могу это исправить? ,

Объявление. 3.

Если, по вашему мнению, String которая следует за кавычками : и выглядит как число, возможно, это символ, который ваша система не декодирует, или невидимый пробел. Очевидно, что " 6" не может быть проанализирован так же, как "123 " не может. Это из-за пробелов. Но может случиться так, что String будет выглядеть как "6" но на самом деле ее длина будет больше, чем количество цифр, которые вы видите.

В этом случае я предлагаю использовать отладчик или хотя бы System.out.println и распечатать длину String которую вы пытаетесь проанализировать. Если он показывает больше, чем количество цифр, попробуйте передать stringToParse.trim() в метод анализа. Если это не сработает, скопируйте всю строку после : и декодируйте ее с помощью онлайн-декодера. Он даст вам коды всех персонажей.

Есть также один случай, который я недавно обнаружил в StackOverflow, который вы могли видеть, что вход выглядит как число, например, "1.86" и он содержит только эти 4 символа, но ошибка все еще существует. Помните, с помощью # Integer # parseInt # можно анализировать только целые числа. Для разбора десятичных чисел следует использовать Double#parseDouble.

Другая ситуация, когда число имеет много цифр. Возможно, он слишком большой или слишком маленький, чтобы соответствовать int или long. Возможно, вы захотите попробовать 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 up to your business logic.
}

Ответ 2

Что такое NumberFormatException?

Это исключение указывается, что приложение имеет попытался преобразовать a 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, чтобы сначала проверить, есть ли string matches с integer, но он довольно подвержен ошибкам, как вы могли легко используйте неправильный regular expression.


В вашем случае вместо использования string следует использовать более OO-подход, например, вы можете использовать class или enum для представления своих карт вместо простого 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, если вы не используете соответствующий индекс).

Ответ 3

Похоже, cards[] - массив String, и вы пытаетесь преобразовать 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

A NumberFormatException - это то, как Java должно сказать вам: "Я попытался преобразовать 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

Самое первое, что бросило меня за цикл (не каламбур), было то, что вы ограничивали значение 1-13, когда ему нужно быть 0-52. Также с вашей логикой значение всегда было выше. Лучший подход - это генератор чисел. Вот мой код с использованием генератора чисел (или 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, я считаю, что Николя Филотто хорошо объяснила это.

Ответ 7

A NumberFormatException означает, что Integer.parseInt() не может перевести строку в число.

Я бы предложил один из двух вариантов:

  • Инкапсулируйте карты как имя (строка)/значение (int). Используйте значение для сравнения и имя для предоставления информации пользователю. Cards[] затем становится списком карт, а не строками.

  • Разбирайте строки самостоятельно. Это может быть проще, поскольку вы уже сделали это с битами if(cards[index].startsWith("Ace")) { value = 1; }. Вы можете переместить их в функцию с именем CardToInt() (или что-то еще) и использовать эту функцию вместо Integer.parseInt().

Ответ 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: указывается, что приложение попыталось преобразовать строку в один из числовых типов, но строка не имеет соответствующего формата. (ref - http://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html)

Ответ 9

Исключение возникает в вашем коде, где вы конвертируете String в Integer:

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

где вы передаете String как "Ace of Clubs" , который невозможно преобразовать как целое, поэтому он генерирует исключение формата номера. Вы можете использовать

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