Вопрос-ответ

What is a NumberFormatException and how can I fix it?

Что такое 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)

Мой цикл 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
Переведено автоматически
Ответ 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'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 предоставила прекрасную трассировку стека, которая точно расскажет вам, в чем проблема. Инструмент, который вы ищете, - это отладчик, и использование точек останова позволит вам проверять состояние вашего приложения в выбранный момент.

Решением может быть следующая логика на случай, если вы хотите использовать синтаксический анализ:

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

Они важны для понимания того, как читать stacktrace. Посмотрите, как 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 считаются шестнадцатеричными цифрами и при необходимости допустимы).

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


  1. Могу ли я прочитать stacktrace?

  2. Это то, String которое вызывает Exception a null?

  3. Похоже ли это на число?

  4. Это "моя строка" или пользовательский ввод?

  5. продолжение следует

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

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

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

Когда вы видите, что вместо "For input string:" и входных данных есть null (не "null"), это означает, что вы пытались передать нулевую ссылку на число. Если вы действительно хотите рассматривать is как 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's up to your business logic.
}
Ответ 2

Что такое NumberFormatException?


Это исключение выдается, чтобы указать, что приложение попыталось преобразовать string в один из числовых типов, но у string нет соответствующего формата.


В вашем случае, согласно вашей трассировке стека, это исключение было сгенерировано Integer.parseInt(String) что означает, что предоставленное String не содержит анализируемого integer. И все же, согласно трассировке стека, это связано с тем, что вы пытались разобрать String "Трефовый туз" как целое число, которое не может работать, поскольку это не String представление целого числа.

Как это исправить?

Самый простой и универсальный способ - перехватить исключение NumberFormatException

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

Это сработает, но перехват исключения происходит медленно, потому что для создания исключения необходимо собрать стек вызовов, Exception что является дорогостоящим, поэтому, если вы можете избежать этого, сделайте это. Кроме того, вам нужно будет правильно управлять исключением, что не всегда очевидно.

Или вы могли бы использовать a regular expression чтобы сначала проверить, является ли String matches с an Integer но это довольно подвержено ошибкам, так как вы могли бы легко использовать неправильный regular expression.


В вашем случае следует использовать более ООП-подход вместо того, чтобы иметь дело с String, например, вы могли бы использовать class или an enum для представления ваших карточек вместо использования simple 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;
}
}

Для масти и ранга карты мы можем использовать an 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, и его можно было бы инициализировать как next:

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 of cards вместо массива, просто используйте Collections.shuffle(list))

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

Тогда вы сможете напрямую обращаться к значению вашей карты с помощью cards[index].getRank().getValue(), не рискуя получить исключение (за исключением IndexOutOfBoundsException, если вы не используете правильный индекс).

Ответ 3

Похоже, что cards[] это строковый массив, и вы пытаетесь преобразовать Ace of Clubs в целое число.

int first_value = Integer.parseInt(cards[index]);
Ответ 4
java.lang.NumberFormatException 

возникает, когда вы пытаетесь проанализировать некоторые входные данные, которые не являются числовой строкой.

В вашем случае вы пытаетесь разобрать строку (которая не имеет числа) как целое число. Поскольку это невозможно, возникло исключение NumberFormatException.

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