Any use of methods that throws exceptions should handle, rethrow, or redeclare (if it is a checked exception) them for the next level up to choose what to do with it.
In Scanner
, if you take nextDouble()
method, it throws various exceptions depending on the status of the scanner. You have to care about it.
But the way to care depend on your program logic.
That said, most exceptions in Scanner
are RuntimeException
, meaning you don’t need to explicitly catch them in your code. Assuming you are in a main
, if an exception occurs, it will be handled by at top level by the JVM. I this case, your program will exit with an error code and a stacktrace.
The only exceptions in Scanner
which are checked and that you must handle in some way, is when you construct a Scanner
from a files. IOException
and FileNotFoundException
cannot be ignored.
As an example of (abused) usage of exceptions when you read a double
, you may be tempted to do:
public static void testScanDoubleWithException() {
Scanner sin = new Scanner(System.in);
System.out.println("Enter a double: ");
while (true) {
try {
double d = sin.nextDouble(); // Throw if not a double
System.out.println("Read double value: "+d);
break;
}
catch (InputMismatchException e) {
System.out.println("Invalid double, shoot again:");
sin.nextLine(); // consume bad input
}
}
sin.close();
}
But the Scanner
class provides the more simple/explicit way:
public static void testScanDouble() {
Scanner sin = new Scanner(System.in);
System.out.println("Enter a double: ");
while (!sin.hasNextDouble()) {
System.out.println("Invalid double, shoot again:");
sin.nextLine();
}
double d = sin.nextDouble();
System.out.println("Read double value: "+d);
sin.close();
}
1. Класс сканера
java.util.Scanner — это новая функция Java5. Мы можем получать вводимые пользователем данные через класс Scanner, а строку ввода — через методы next () и nextLine () класса Scanner. Обычно нам нужно использовать hasNext перед чтением Проверьте с помощью hasNextLine, есть ли еще входные данные.
Ниже приводится базовый синтаксис для создания объекта сканера:
Scanner s = new Scanner(System.in);
Разница между next () и nextLine ()
next():
1. Вы должны прочитать допустимые символы, прежде чем сможете завершить ввод.
2. Метод next () автоматически удаляет пробелы, встречающиеся перед вводом допустимых символов.
3. Только после ввода действительных символов пробелы, введенные после них, используются как разделители или терминаторы.
4. Next () не может получить строку с пробелами.
nextLine():
1. Возьмите Enter в качестве терминатора, что означает, что метод nextLine () возвращает все символы перед возвратом каретки.
2. Можно получить пустое поле.
Если вы хотите ввести данные типа int или float, он также поддерживается в классе Scanner, но лучше всего использовать метод hasNextXxx () для проверки перед вводом, а затем использовать nextXxx () для чтения:
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
// Получаем данные с клавиатуры
int i = 0;
float f = 0.0f;
System.out.print("Введите целое число:");
if (scan.hasNextInt()) {
// Определяем, является ли ввод целым числом
i = scan.nextInt();
// получаем целое число
System.out.println("Целочисленные данные:" + i);
} else {
// Ввод неверной информации
System.out.println("Введено не целое число!");
}
System.out.print("Введите десятичную дробь:");
if (scan.hasNextFloat()) {
// Определяем, является ли ввод десятичным
f = scan.nextFloat();
// получаем десятичную дробь
System.out.println("Десятичные данные:" + f);
} else {
// Ввод неверной информации
System.out.println("Ввод не десятичный!");
}
scan.close();
}
}
Результат вышеупомянутой программы:
$ javac ScannerDemo.java
$ java ScannerDemo
Введите целое число:12
Целочисленные данные:12
Введите десятичное число:1.2
Десятичные данные:1.2
2. Обработка исключений Java
Исключения — это некоторые ошибки в программе, но не все ошибки являются исключениями, и ошибок иногда можно избежать.
Чтобы понять, как работает обработка исключений Java, вам необходимо освоить следующие три типа исключений:
- Нарушение исследования: наиболее репрезентативное отклонение от нормы исследованияИсключения, вызванные ошибками или проблемами пользователя, Программисты этого не предвидят. Например, при открытии несуществующего файла возникает исключение.Эти исключения нельзя просто игнорировать во время компиляции.
- Исключение времени выполнения:Исключения времени выполнения — это исключения, которых программисты могут избежать.. В отличие от проверенных исключений, исключения времени выполнениямочьИгнорируется во время компиляции.
- Ошибка: ошибка — это не исключение, а проблема, не зависящая от программиста. Ошибки в коде обычно игнорируются. Например, при переполнении стека возникает ошибка,Их нельзя проверить даже во время компиляции。
Ноты:
1. Проверяемое исключение: компиляция не выполняется без обработки.
2. Непроверенное исключение: компиляцию можно передать без обработки, если она передается непосредственно в консоль.
3、Исключения времени выполнения: непроверенные исключения
4、Исключение не во время выполнения: проверенное исключение
2.1 Иерархия класса Exception
Все классы исключений являются подклассами, унаследованными от класса java.lang.Exception.
Класс исключения является подклассом класса Throwable. В дополнение к классу Exception,Throwable также имеет подкласс Error.
Программы на Java обычно не обнаруживают ошибок. Ошибки обычно возникают при серьезных сбоях, и они выходят за рамки программы Java.
Ошибка используется для обозначения ошибки, возникшей в среде выполнения.
Например, переполнение памяти JVM. обычно,Программа не восстановится после ошибки。
Класс исключения имеет два основных подкласса: класс IOException и класс RuntimeException.
2.2 Встроенные классы исключений Java
Встроенные классы исключений Java имеют большинство обычно используемых отмеченных и непроверенных исключений. Язык Java определяет некоторые классы исключений в стандартном пакете java.lang. Подклассы стандартных классов исключений среды выполнения являются наиболее распространенными классами исключений.Поскольку пакет java.lang по умолчанию загружается во все программы Java, Таким образом, большинство исключений, унаследованных от класса исключений времени выполнения, можно использовать напрямую.
2.3 Исключения из улова
Используйте ключевые слова try и catch, чтобы поймать исключения. Блок кода try / catch размещается там, где может возникнуть исключение.
Вызывается код в блоке try / catchКод защиты, Синтаксис использования try / catch следующий:
try
{
// код
}catch(ExceptionName e1)
{
// Поймать блок
}
Оператор Catch содержит объявление типа исключения, которое необходимо перехватить. Когда в защищенном блоке кода возникает исключение, проверяется блок catch после попытки.
Если возникшее исключение содержится в блоке catch,Исключение будет передано в блок catch, что аналогично передаче параметра методу.
2.4 Множественные блоки захвата
Блок кода попытки, за которым следует несколько блоков кода перехвата, называется множественным перехватом.
Синтаксис блока множественного захвата следующий:
try{
// код
}catch(Тип исключения1 Ненормальное имя переменной1){
// код
}catch(Тип исключения2 Ненормальное имя переменной2){
// код
}catch(Тип исключения2 Ненормальное имя переменной2){
// код
}
Приведенный выше фрагмент кода содержит 3 блока catch.
Вы можете добавить любое количество блоков catch после оператора try.
Если в коде защиты возникает исключение, исключение переходит в первый блок catch.
Если тип данных вызванного исключения соответствует ExceptionType1, оно будет перехвачено здесь.
Если он не совпадает, он будет передан во второй блок catch.
Итак, пока исключение не будет перехвачено или не пройдёт все блоки catch.
2.5 броска / броска ключевые слова:
Если метод не обнаруживает проверенное исключение,Затем метод должен быть объявлен с использованием ключевого слова throws. Ключевое слово throws помещается в конец сигнатуры метода.
также может использовать ключевое слово throw для создания исключения, независимо от того, создано ли оно заново или только что.
Следующее объявление метода вызывает исключение RemoteException:
import java.io.*;
public class className
{
public void deposit(double amount) throws RemoteException
{
// Method implementation
throw new RemoteException();
}
//Remainder of class definition
}
Метод может объявить, что генерирует несколько исключений, разделенных запятыми.
2.6 наконец ключевое слово
Ключевое слово finally используется для создания блока кода, который выполняется после блока кода try.
Независимо от того, возникает ли исключение, код в блоке кода finally всегда будет выполняться。
В блоке кода finally вы можете запускать типы очистки и другие операторы завершения.
Обратите внимание на следующее:
- Улов не может существовать независимо от попытки.
- Добавлять блок finally после try / catch не обязательно.
- После кода попытки не может быть ни блока catch, ни блока finally.
- Между блоками try, catch и finally нельзя добавить код.
2.7 Объявление пользовательских исключений
Вы можете настроить исключения в Java. При написании собственного класса исключений необходимо учитывать следующие моменты.
Все исключения должны быть подклассом Throwable.
Если вы хотите написать проверенный класс исключения, вам необходимо унаследовать класс Exception.
Если вы хотите написать класс исключения времени выполнения, вам необходимо унаследовать класс RuntimeException.
Вы можете определить свой собственный класс исключения следующим образом:
class MyException extends Exception{
...
}
Класс исключения, созданный путем наследования только класса Exception, является проверенным классом исключения.
Пример
Следующий пример представляет собой симуляцию банковского счета. Идентификация завершается по номеру банковской карты, и можно выполнять операции по внесению и снятию денег.
Код файла InsfficientFundsException.java:
// Имя файла InsfficientFundsException.java
import java.io.*;
// Пользовательский класс исключения, наследующий класс исключения
public class InsufficientFundsException extends Exception
{
// Сумма здесь используется для хранения денег, которые отсутствуют при возникновении исключения (когда снято больше денег, чем на балансе)
private double amount; // приватизация, полученная с помощью getAmount ()
public InsufficientFundsException(double amount)
{
this.amount = amount;
}
public double getAmount()
{
return amount;
}
}
Чтобы показать, как использовать наш настраиваемый класс исключений, включите метод remove () в класс CheckingAccount ниже, чтобы вызвать исключение ShouldFundsException.
Код файла CheckingAccount.java:
// Имя файла CheckingAccount.java
import java.io.*;
// Такой симулированный банковский счет
public class CheckingAccount
{
// баланс - это баланс, number - номер карты
private double balance;
private int number;
public CheckingAccount(int number)
{
this.number = number;
}
// Метод: внести деньги
public void deposit(double amount)
{
balance += amount;
}
// Метод: вывод денег
public void withdraw(double amount) throws
InsufficientFundsException
{
if(amount <= balance)
{
balance -= amount;
}
else
{
double needs = amount - balance;
throw new InsufficientFundsException(needs);
}
}
// Метод: вернуть баланс
public double getBalance()
{
return balance;
}
// Метод: вернуть номер карты
public int getNumber()
{
return number;
}
}
Следующая программа BankDemo демонстрирует, как вызвать методы deposit () и remove () класса CheckingAccount.
Код файла BankDemo.java:
// Имя файла BankDemo.java
public class BankDemo
{
public static void main(String [] args)
{
CheckingAccount c = new CheckingAccount(101);
System.out.println("Depositing $500...");
c.deposit(500.00);
try
{
System.out.println("\nWithdrawing $100...");
c.withdraw(100.00);
System.out.println("\nWithdrawing $600...");
c.withdraw(600.00);
}catch(InsufficientFundsException e)
{
System.out.println("Sorry, but you are short $"
+ e.getAmount());
e.printStackTrace();
}
}
}
Скомпилируйте указанные выше три файла и запустите программу BankDemo, результаты будут следующими:
Depositing $500...
Withdrawing $100...
Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
at CheckingAccount.withdraw(CheckingAccount.java:25)
at BankDemo.main(BankDemo.java:13)
2.8 Общее исключение
В Java определены два типа исключений и ошибок.
- Исключения JVM (виртуальная машина Java): исключения или ошибки, создаваемые JVM. Например: класс NullPointerException, класс ArrayIndexOutOfBoundsException, класс ClassCastException.
- Исключения на уровне программы: исключения, создаваемые программами или программами API. Например, класс IllegalArgumentException, класс IllegalStateException.
2.9 Ненормальное использование может соответствовать следующим принципам:
1: Когда текущий метод перезаписывается, перезаписывающий метод должен генерировать то же исключение или подкласс исключения;
2: используйте оператор try-catch для перехвата исключения в текущем объявлении метода;
3: если родительский класс генерирует несколько исключений, метод переопределения должен генерировать подмножество этих исключений и не может генерировать новые исключения.
2.10 Сводка исключений:
Как показано на рисунке, все исключения и ошибки наследуются от класса Throwable, что означает, что все исключения являются объектом.
примерно разделите исключение на две части:
1. Ошибка — ошибка: относится к ошибке, которую программа не может обработать, и представляет собой серьезную ошибку, которая возникает во время работы приложения. Например, OutOfMemoryError во время работы jvm и занятый порт во время программирования Socket — это ошибки, которые программа не может обработать.
2. Exception — исключение: исключения можно разделить на исключения времени выполнения и исключения компиляции.
(1) Исключение времени выполнения: RuntimeException и другие исключения. Этот тип исключения не будет обнаружен компилятором при написании кода, и его не нужно перехватывать, но программист также может поймать и выбросить по мере необходимости. Общие исключения RUNtimeExceptions включают в себя: NullpointException (исключение нулевого указателя), ClassCastException (исключение преобразования типа), IndexOutOfBoundsException (исключение массива вне границ) и т. Д.
(2) Исключение компиляции: исключения, отличные от RuntimeException. Компилятор предложит вам зафиксировать этот тип исключения во время компиляции. Если вы не зафиксируете его, произойдет ошибка компиляции. Общие исключения компиляции включают: IOException (исключение передачи потока), SQLException (исключение операции с базой данных) и т. Д.
3. Механизм Java для обработки исключений: выдача исключений и перехват исключений Исключение, которое может перехватить метод, должно быть исключением, сгенерированным где-то кодом Java. вообще говоря,Исключения всегда сначала генерируются, а затем перехватываются。
4. Разница между броском и броском:
public void test() throws Exception {
throw new Exception();
}
Разницу между ними ясно видно из приведенного выше кода.. Throws означает, что объявление метода может вызвать исключение, а throw означает, что здесь выбрасывается определенное исключение (это может быть обычное наследование Exception, или это может быть класс исключения, предоставленный самой Java).
5. Давайте посмотрим, как перехватывать исключения:
(1) Прежде всего, java использует блок кода try-catch или try-catch-finally для захвата исключения, программа захватит код в блоке кода try, и если он улавливает исключение, он перехватит обработку блока кода. Если есть finally, выполните код в finally после обработки catch. Однако есть две проблемы:
а. Посмотрите на следующий код:
try{
// Код для записи
}catch(Exception e){
System.out.println("catch is begin");
return 1 ;
}finally{
System.out.println("finally is begin");
}
Есть отдача в улове, исполнится окончательно? Ответ — да, результат выполнения приведенного выше кода:
catch is begin
finally is begin
То есть сначала будет выполнен код в catch, затем код в finally будет выполнен перед возвратом1;
б. Посмотрите на следующий код:
try{
// Код для записи
}catch(Exception e){
System.out.println("catch is begin");
return 1 ;
}finally{
System.out.println("finally is begin");
return 2 ;
}
В коде b выходной результат такой же, как у a, но возвращается return 2;Причина очевидна, то есть возврат был выполнен после finally, поэтому возврат в catch не будет выполнен.Другими словами, finally всегда будет выполняться перед возвратом улова. (Это вопрос, который часто задают в интервью!)
6. Не должно быть удобно захватывать исключения и объединять несколько исключений в одно исключение для захвата, например исключения ввода-вывода и исключения SQL, чтобы два совершенно разных исключения обрабатывались отдельно!И при обработке исключений в catch не просто используйте e.printStackTrace (), а обрабатывайте их подробно. Например, сведения о печати с консоли или записи журнала.
Примечание. Разница между исключениями и ошибками: исключения могут обрабатываться самой программой, но ошибки не могут быть обработаны.
Язык Java определяет некоторые классы исключений в стандартном пакете java.lang. Подклассы стандартных классов исключений среды выполнения являются наиболее распространенными классами исключений. Поскольку пакет java.lang загружается во все программы Java по умолчанию, большинство исключений, унаследованных от классов исключений времени выполнения, можно использовать напрямую.
Примечание: finally может не выполняться, например, если есть оператор для выхода из системы в блоке catch System.exit (-1); finally не будет выполнен
Из:http://www.runoob.com/java/java-exceptions.html
Note that you actually do not handle the exceptions. It’s not your fault, as there’s not enough context for really handling them. Is printing the stacktrace to the error output appropriate? In this case it may be the right thing, but usually it’s not. Surprisingly, doing nothing is mostly best — note that the java.io
classes also throw without any «handling».
So I’d simplify rolfl’s code to
public static void main(String[] args) throws IOException, InputMismatchException {
try (Scanner inFile = new Scanner(new FileReader("sample.txt"))) {
int num1 = inFile.nextInt();
int num2 = inFile.nextInt();
int sum = num1 + num2;
System.out.println("sum " + sum);
}
}
When an exception gets thrown, the stacktrace gets printed anyway (in my solution the exact behavior is OS dependent, but this may be an advantage).
There’s one more difference: Not catching means that the program returns a non-zero status (on systems supporting it, i.e., at least UNIX and Windows), which clearly indicates a problem.
Вы можете использовать hasNextInt()
, чтобы убедиться, что Scanner
будет успешным, если вы выполните nextInt()
. Вы также можете вызывать и отбрасывать nextLine()
, если вы хотите пропустить «мусор».
Итак, что-то вроде этого:
Scanner sc = new Scanner(System.in);
while (!sc.hasNextInt()) {
System.out.println("int, please!");
sc.nextLine();
}
int num = sc.nextInt();
System.out.println("Thank you! (" + num + ")");
См. также:
- Как заставить сканер отбрасывать исключения при вводе неправильного типа? (java)
Проблема с вашим кодом в дополнение к ненужно сложной обработке ошибок, поскольку вы позволяете nextInt()
выкидывать InputMismatchException
вместо проверки на hasNextInt()
, заключается в том, что когда он генерирует исключение, вы не продвигаетесь Scanner
мимо проблематичного ввода! Вот почему вы получаете бесконечный цикл!
Вы можете вызывать и отбрасывать nextLine()
, чтобы исправить это, но еще лучше, если вы используете вместо этого исключающую исключение hasNextInt()
технику предварительной проверки.
Chapter 13: Handling Exceptions, Input Validation, Try/Catch Blocks
In this chapter, you will learn ways to prevent users from unintentionally crashing your programs. The focus will be on try/catch blocks and using specific scanner methods to read certain data types and prevent exceptions from occurring.
13.1 Exceptions
Up to this point in the series, all code shown requiring user input has assumed that the user knows exactly what they’re doing and that they won’t make mistakes or typos. What happens if we ask the user to type a number and they type a letter instead? What if we ask them to select from 3 choices — 1, 2, or 3, and they accidentally enter 4? Chances are the program will crash. In production, we cannot let this happen. A program shouldn’t crash just because a user made a mistake. We need to review their input, display feedback for any issues, and ask them to try something else.
When Java encounters a preventable error, an exception is thrown. An exception is defined as any event that occurs which disrupts the regular flow of a program’s execution. We have previously discussed a few exceptions. One example from recent chapters is the IndexOutOfBounds exception, which occurs when a program tries to access a value in an array which does not exist (like trying to get the 50th element of a 5 element array).
Exceptions are similar to Errors. They both interrupt a program and may cause crashes. However, Errors indicate a deeper problem with the software and may result from some type of logic error on the programmer’s part. Exceptions are preventable issues usually caused by mistakes which can be corrected during runtime without entirely crashing the program. If your program runs out of system memory because you’re dealing with massive amounts of data, or you’ve created too many large objects, there’s not much the end user can do to resolve it. That will result in an OutOfMemory Error and the program will crash. If the program has a problem because a user typed the letter A instead of 1, that is an easily resolvable exception.
InputMismatchException
Consider the following code, which asks the user to enter a number and then prints out that entered number multiplied by two.
Ex. 13.1 — Multiply by Two
int x;
Scanner input = new Scanner(System.in);
System.out.println("Type a number:");
//read the next int
x = input.nextInt();
//multiply by two and close the scanner
System.out.println("x times two is: " + (x * 2));
input.close();
If the user enters an int, the program executes as expected.
Type a number: 5 x times two is: 10
Now let’s see what happens if we enter something else. Like the word «apple.»
Type a number: apple Exception in thread "main" java.util.InputMismatchException at java.base/java.util.Scanner.throwFor(Scanner.java:943) at java.base/java.util.Scanner.next(Scanner.java:1598) at java.base/java.util.Scanner.nextInt(Scanner.java:2263) at java.base/java.util.Scanner.nextInt(Scanner.java:2217) at Main.main(Main.java:12)
Since the word «apple» is a String and not an int, an InputMismatchException has occurred. The input did not match the expected data type.
The easiest way to handle the above exception is to use a try/catch block.
13.2 Try/Catch Blocks
Try/Catch blocks are ways to «try» to execute code and «catch» any exceptions. It’s like telling the computer to try something, and if it fails, do this instead.
The structure of a try/catch block is as follows:
13.2a — Try/Catch Template
try{
//code to do
}
catch(Exception e){
//block of code to handle exceptions
}
finally{
//do this always when try/catch is complete
}
The try block is the set of code we are trying to execute. The catch block catches the exception. It gets executed when an exception occurs. An exception is a particular type of object in Java that gets «thrown» when an issue arises. The above example catches all exceptions, but it is possible to catch specific exceptions and do different things depending on which exception was caught. The finally block is optional. It is executed at the end, regardless of whether an exception occurred.
Here is a flowchart of the execution process:
Checking user input to make sure it’s in the right format is known as input validation. Let’s change example 13.1 to catch the possible InputMismatchException. This time, it will print out a message saying the user did not enter a number, rather than showing them an Exception.
13.2b — Basic Handling
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int x;
//open scanner
Scanner input = new Scanner(System.in);
System.out.println("Type a number:");
try{
//read the number
x = input.nextInt();
//print number multiplied by two
System.out.println("x times two is: " + (x * 2));
}
catch(Exception e){
System.out.println("Something went wrong, relaunch the program to try again.");
}
finally{
System.out.println("All done!");
input.close();
}
}
}
Now, when I enter a number, this happens:
Type a number: 5 x times two is: 10 All done!
And when I type something else, this happens:
Type a number: apple Something went wrong, relaunch the program to try again. All done!
People unfamiliar with Java likely won’t know what an InputMismatchException means. Now the program is a bit more understandable by an average user. We have printed a more human-readable message explaining what went wrong and how the user can correct it.
Notice that the «All done!» text was printed to the console in both scenarios, since it’s in the finally block.
Next, let’s improve the program further. Rather than ending the program when the user enters an incorrect value and asking them to restart the program, we can ask them to try again and enter the correct value without restarting the program.
The easiest way to do this will be to place the operations in a while loop. When a number is entered correctly, we break the loop. If a number is entered incorrectly, the loop repeats.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int x;
//open scanner
Scanner input = new Scanner(System.in);
while (true) {
try {
System.out.println("Type a number:");
//read the number
x = input.nextInt();
//print number multiplied by two
System.out.println("x times two is: " + (x * 2));
//we have gotten to this point without issue, we can end the loop
break;
} catch (Exception e) {
System.out.println("Something went wrong, let's try that again.");
//tell scanner to go to the next line to prevent infinite loop of scanner reading printout
input.nextLine();
//since it's a while true loop, it will just repeat until the try block executes fully
}
}
//remember to close scanner
input.close();
}
}
Now, when I run the program, I can keep trying until I enter a number properly.
Type a number: banana Something went wrong, let's try that again. Type a number: muffins Something went wrong, let's try that again. Type a number: 5 x times two is: 10
Note that input.close();
came outside the try/catch block and the loop. This is to leave it open in case an exception happens and the user wants to try again.
13.3 Handling Multiple Exceptions
Next, let’s consider a program that takes two numbers as input and divides the first by the second.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//initialize vars
int a;
int b;
Scanner input = new Scanner(System.in);
//record input
System.out.println("Enter first number:");
a = input.nextInt();
System.out.println("Enter second number:");
b = input.nextInt();
//close scanner
input.close();
//display results
int result = a / b;
System.out.println("a / b is: " + result);
}
}
Like the previous example, it’s possible to get an InputMismatchException from the code above.
Enter first number: apple Exception in thread "main" java.util.InputMismatchException
Additionally, it’s possible to get an ArithmeticException if the user attempts to divide by zero (you can’t divide by zero).
Enter first number: 100 Enter second number: 0 Exception in thread "main" java.lang.ArithmeticException: / by zero at Main.main(Main.java:21)
You could handle this one of two ways. First, you could do something similar to the multiplication example. catch (Exception e)
catches all exceptions. You could generically say something went wrong and have them try again.
Instead, let’s inform the user with a message of their exact mistake. They either 1) did not enter valid ints or 2) tried to divide by zero. To do this, we will use multiple catch blocks and specifically define the exception type.
import java.util.InputMismatchException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//initialize vars
int a;
int b;
int result = 0;
Scanner input = new Scanner(System.in);
while (true) {
try {
//record input
System.out.println("Enter first number:");
a = input.nextInt();
System.out.println("Enter second number:");
b = input.nextInt();
//calc results
result = a / b;
//if we get here, haven't experienced an exception, can leave the loop
break;
}
//catch the ArithmeticException
catch (ArithmeticException e) {
System.out.println("Oops. Arithmetic problem - don't divide by zero. Try again.");
input.nextLine();
}
//catch the InputMismatchException
catch (InputMismatchException e) {
System.out.println("You must enter whole numbers only. No decimals, words, or other info. Try again.");
input.nextLine();
}
//catch any other possible exceptions
catch (Exception e) {
System.out.println("Something else must have gone wrong...");
//print the exception error info
e.printStackTrace();
break;
}
}
//close scanner
input.close();
//display result
System.out.println("a / b is: " + result);
}
}
Now you can see, it tells the user exactly what went wrong and allows them to retry until they get the input right.
Enter first number: apple You must enter whole numbers only. No decimals, words, or other info. Try again. Enter first number: 100 Enter second number: 0 Oops. Arithmetic problem - don't divide by zero. Try again. Enter first number: 5 Enter second number: 5 a / b is: 1
Note that the last catch block catches any other exception aside from the two specified exceptions before it. If this happens, e.printStackTrace();
will print out the exact exception details and the loop will be broken.
You may also catch multiple specified exception types in one catch block using the or operator:
try {
//code to try
}
catch (ArithmeticException|InputMismatchException e){
System.out.println("Problem with arithmetic or input");
}
Scanner Tip: Remember, when using the Scanner for System InputStream (System.in), only close it after your program is entirely done using it. You cannot close and re-open it if you need it later without restarting the program.
13.4 Common Exception Types
Besides the ArithmeticException and InputMismatchException, here are examples of some other common exceptions you may run into.
ArrayIndexOutOfBoundsException
The ArrayIndexOutOfBoundsException occurs when you attempt to access an element of an array that does not exist.
Prevention: Ensure your program does not access indices which do not exist. Use the array.length variable to check array size before attempting to manipulate or add additional values to it.
Example
try{
int[] arr = new int[5];
arr[6] = 7;
}
catch (ArrayIndexOutOfBoundsException e){
System.out.println("The array only has 5 elements, you tried to access index 6.");
e.printStackTrace();
}
StringIndexOutOfBoundsException
A StringIndexOutOfBoundsException occurs when you attempt to modify or access a character beyond the bounds of a given string. For example, trying to get the 50th char of a String that’s shorter than that.
Example
try{
String s = "Hello there.";
char c = s.charAt(50);
}
catch (StringIndexOutOfBoundsException e){
System.out.println("tried to get a char that's not there");
}
NullPointerException
A NullPointerException occurs when the program attempts to access information from a variable reference which is pointing to nothing or a null value.
Prevention: Trace where the null value came from and ensure it’s initialized with a value prior to using.
Example
public class Main {
public static void main(String[] args) {
try{
doSomethingWithVariable(null);
}
catch (NullPointerException e){
System.out.println("x is null");
}
}
public static void doSomethingWithVariable(Integer x){
System.out.println("The value times two is: " + (x * 2));
}
}
IllegalArgumentException
An IllegalArgumentException occurs when you pass an argument to a method that is invalid. It may be the right data type, but it might not make sense within the context of the method being called. The argument is «illegal».
A BigInteger can be created by parsing a number from a string, e.g. «3.14» — if you use a string that doesn’t contain numbers, an IllegalArgumentException will be thrown.
Example
try{
//try to make a BigInteger with a string of text instead of numbers
BigInteger bigint = new BigInteger("Muffins");
}
catch (IllegalArgumentException e){
System.out.println("That's not a valid argument");
}
FileNotFoundException
A FileNotFoundException occurs when a program attempts to access a file which does not exist on the file system. Usually this is because the file was spelled incorrectly, or was deleted/moved.
We will discuss files in greater detail in the next chapter.
13.5 Throwing Exceptions
In addition to catching exceptions, it’s possible to design methods which throw their own exceptions.
In Java, you may divide doubles by zero and get a result of infinity (dividing ints by zero throws an ArithmeticException).
System.out.println(100.0/0.0);
Infinity
Say, for example, that you want to create a new method to divide doubles. It will take two doubles as arguments and return the result of dividing the first by the second. The code is below:
public class Main {
public static void main(String[] args) {
System.out.println("100 divided by zero is: " + divide(100, 0));
}
public static double divide(double a, double b) {
return a / b;
}
}
100 divided by zero is: Infinity
Suppose you want to change the behavior of the method so that it still divides doubles, but intentionally cannot divide by zero. We can design the method so that it throws an exception. We can select what type of exception we want to throw. In this case, an IllegalArgumentException or an ArithmeticException makes sense. The ArithmeticException may be the better choice here, since it’s more specific.
To throw this exception, you need to add the throws keyword to the method declaration and define what type of exception the method will throw.
public static double divide(double a, double b) throws ArithmeticException{
Next, specify the scenario in which the exception gets thrown. In this case, if the second variable is 0, an ArithmeticException will be thrown. Throw it using the throw keyword.
public class Main {
public static void main(String[] args) {
System.out.println("100 divided by zero is: " + divide(100, 0));
}
public static double divide(double a, double b) throws ArithmeticException {
if (b == 0) {
throw new ArithmeticException();
} else {
return a / b;
}
}
}
Now, when I run the program and try to divide by zero using the divide method, an exception is thrown, rather than getting the previous result of infinity.
Exception in thread "main" java.lang.ArithmeticException at Main.divide(Main.java:11) at Main.main(Main.java:4)
The exception may then be caught the same way as discussed earlier.
Conclusion/Review
You should now understand how to validate user input, check exceptions, and throw exceptions. This will be important in future chapters.
Review: Go back and retry the examples in this chapter yourself.
Assignment: The Integer.parseInt()
method can be used to «parse» or convert a number given in the form of a String into an int.
For example, the code below assigns a value of 5 to x.
int x = Integer.parseInt("5");
Create a similar method called parseSingleInt which takes a single char as a parameter and returns the equivalent single-digit integer. For example: int x = parseSingleInt('5');
would set x to 5. If the user enters any other character than 0 through 9, it should return an IllegalArgumentException.
The main method should set int x to 5, add 5 to it, and print out 10 using the parseSingleInt method. Then, an exception should be thrown when y is set to the value of ‘a’. Surround the code setting y to ‘a’ in a try/catch block and catch the exception. Print out a message saying «Invalid number entered.» in the catch block.
Hint: You can do this by checking if char c is equal to ‘0’ and then return 0, ‘1’ returns 1, and so on. You may do this using if conditions or a switch. When you get through the list of all 10 digits 0 through 9, throw the exception.
public class Main {
public static void main(String[] args) {
int x = parseSingleInt('5');
x += 5;
System.out.println("This should print out the number ten: " + x);
//this should throw an exception since a is not a single number
System.out.println("Trying to set y to a");
int y = parseSingleInt('a');
}
public static int parseSingleInt(char c) throws IllegalArgumentException {
//your code here
}
}
Sample output:
This should print out the number ten: 10 Trying to set y to a Invalid number entered.
Go To Chapter 14: File IO