Chapter 13: Exception Handling - Preventing Errors
Part 13 of 17 in Intro to Java SeriesNext: Chapter 14: Basic File Input/Output →

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 the programs requiring user input have 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 on 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 show 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 cause 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
1int x;
2Scanner input = new Scanner(System.in);
3
4System.out.println("Type a number:");
5
6//read the next int
7x = input.nextInt();
8
9//multiply by two and close the scanner
10System.out.println("x times two is: " + (x * 2));
11input.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
1try{
2 //code to do
3 }
4 catch(Exception e){
5 //block of code to handle exceptions
6 }
7finally{
8 //do this always when try/catch is complete
9}
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
1import java.util.Scanner;
2
3public class Main {
4 public static void main(String[] args) {
5
6 int x;
7 //open scanner
8 Scanner input = new Scanner(System.in);
9 System.out.println("Type a number:");
10
11 try{
12 //read the number
13 x = input.nextInt();
14 //print number multiplied by two
15 System.out.println("x times two is: " + (x * 2));
16
17 }
18 catch(Exception e){
19 System.out.println("Something went wrong, relaunch the program to try again.");
20 }
21 finally{
22 System.out.println("All done!");
23 input.close();
24 }
25
26
27
28 }
29}
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.
1import java.util.Scanner;
2
3public class Main {
4 public static void main(String[] args) {
5
6 int x;
7 //open scanner
8 Scanner input = new Scanner(System.in);
9
10
11 while (true) {
12 try {
13
14 System.out.println("Type a number:");
15 //read the number
16 x = input.nextInt();
17 //print number multiplied by two
18 System.out.println("x times two is: " + (x * 2));
19 //we have gotten to this point without issue, we can end the loop
20 break;
21
22 } catch (Exception e) {
23 System.out.println("Something went wrong, let's try that again.");
24 //tell scanner to go to the next line to prevent infinite loop of scanner reading printout
25 input.nextLine();
26 //since it's a while true loop, it will just repeat until the try block executes fully
27
28 }
29 }
30
31 //remember to close scanner
32 input.close();
33
34
35 }
36}
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.
1import java.util.Scanner;
2
3public class Main {
4 public static void main(String[] args) {
5
6 //initialize vars
7 int a;
8 int b;
9 Scanner input = new Scanner(System.in);
10
11 //record input
12 System.out.println("Enter first number:");
13 a = input.nextInt();
14 System.out.println("Enter second number:");
15 b = input.nextInt();
16
17 //close scanner
18 input.close();
19
20 //display results
21 int result = a / b;
22 System.out.println("a / b is: " + result);
23
24 }
25}
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.
1import java.util.InputMismatchException;
2import java.util.Scanner;
3
4public class Main {
5 public static void main(String[] args) {
6
7 //initialize vars
8 int a;
9 int b;
10 int result = 0;
11 Scanner input = new Scanner(System.in);
12
13 while (true) {
14 try {
15 //record input
16 System.out.println("Enter first number:");
17 a = input.nextInt();
18 System.out.println("Enter second number:");
19 b = input.nextInt();
20 //calc results
21 result = a / b;
22 //if we get here, haven't experienced an exception, can leave the loop
23 break;
24 }
25 //catch the ArithmeticException
26 catch (ArithmeticException e) {
27 System.out.println("Oops. Arithmetic problem - don't divide by zero. Try again.");
28 input.nextLine();
29 }
30 //catch the InputMismatchException
31 catch (InputMismatchException e) {
32 System.out.println("You must enter whole numbers only. No decimals, words, or other info. Try again.");
33 input.nextLine();
34 }
35 //catch any other possible exceptions
36 catch (Exception e) {
37 System.out.println("Something else must have gone wrong...");
38 //print the exception error info
39 e.printStackTrace();
40 break;
41 }
42 }
43
44 //close scanner
45 input.close();
46
47 //display result
48 System.out.println("a / b is: " + result);
49
50 }
51}
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:
1try {
2 //code to try
3}
4catch (ArithmeticException|InputMismatchException e){
5 System.out.println("Problem with arithmetic or input");
6}
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:
1try{
2 int[] arr = new int[5];
3 arr[6] = 7;
4}
5catch (ArrayIndexOutOfBoundsException e){
6 System.out.println("The array only has 5 elements, you tried to access index 6.");
7 e.printStackTrace();
8}
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
1try{
2 String s = "Hello there.";
3 char c = s.charAt(50);
4
5}
6catch (StringIndexOutOfBoundsException e){
7 System.out.println("tried to get a char that's not there");
8}
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
1public class Main {
2 public static void main(String[] args) {
3
4 try{
5
6 doSomethingWithVariable(null);
7
8 }
9 catch (NullPointerException e){
10 System.out.println("x is null");
11 }
12
13 }
14
15 public static void doSomethingWithVariable(Integer x){
16 System.out.println("The value times two is: " + (x * 2));
17 }
18}
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
1try{
2 //try to make a BigInteger with a string of text instead of numbers
3 BigInteger bigint = new BigInteger("Muffins");
4}
5catch (IllegalArgumentException e){
6 System.out.println("That's not a valid argument");
7}
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).
1System.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:
1public class Main {
2 public static void main(String[] args) {
3
4 System.out.println("100 divided by zero is: " + divide(100, 0));
5
6 }
7
8 public static double divide(double a, double b) {
9
10 return a / b;
11
12 }
13
14}
1100 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.
1public 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.
1public class Main {
2 public static void main(String[] args) {
3
4 System.out.println("100 divided by zero is: " + divide(100, 0));
5
6 }
7
8 public static double divide(double a, double b) throws ArithmeticException {
9
10 if (b == 0) {
11 throw new ArithmeticException();
12 } else {
13 return a / b;
14 }
15
16 }
17
18}
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.
1int 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.
1public class Main {
2 public static void main(String[] args) {
3
4 int x = parseSingleInt('5');
5 x += 5;
6 System.out.println("This should print out the number ten: " + x);
7
8 //this should throw an exception since a is not a single number
9 System.out.println("Trying to set y to a");
10 int y = parseSingleInt('a');
11
12
13 }
14
15 public static int parseSingleInt(char c) throws IllegalArgumentException {
16 //your code here
17 }
18
19}
Sample output:
This should print out the number ten: 10 Trying to set y to a Invalid number entered.
Chapter 13 Review Solution
1public class Main {
2 public static void main(String[] args) {
3
4 int x = parseSingleInt('5');
5 x += 5;
6 System.out.println("This should print out the number ten: " + x);
7
8 try {
9 //this should throw an exception since a is not a single number
10 System.out.println("Trying to set y to a");
11 int y = parseSingleInt('a');
12 } catch (IllegalArgumentException e) {
13 System.out.println("Invalid number entered.");
14 }
15
16
17 }
18
19 public static int parseSingleInt(char c) throws IllegalArgumentException {
20 switch (c) {
21 case '0':
22 return 0;
23 case '1':
24 return 1;
25 case '2':
26 return 2;
27 case '3':
28 return 3;
29 case '4':
30 return 4;
31 case '5':
32 return 5;
33 case '6':
34 return 6;
35 case '7':
36 return 7;
37 case '8':
38 return 8;
39 case '9':
40 return 9;
41 }
42 //if we get to this point, we have gone through all 10 possibilities without getting an int between 0 and 9, throw an exception
43 throw new IllegalArgumentException();
44 }
45
46}
Spotted a mistake? Select the sentence in the guide and choose “Suggest a fix”.
Related guides
Simple Pong (Extras)
This guide is a continuation of the previous Simple Pong project. I'd encourage you to begin there if you haven't already. In this guide, you will learn how to…
Simple 2D Pong
The game will contain 4 classes. Main - Launches the program, starts the game and game timerPongGame - Extends JPanel, serves as the game's canvas, tracks…
GUI Blackjack
In this project, we will expand upon the earlier console blackjack project. You should begin there if you haven't already. This project relies on much of the…

Comments
Found an error? instead, it reaches me faster.No comments yet. Questions and corrections are welcome.