Exceptions

Updated: 3 years ago

Check out other lessons in Learning the Java syntax

Oh no, your application just crashed and everything is red. That's not good. Let's help out our application by handling exceptions and making sure that our users never experience a crash ever again.

Run this piece of code and instead of a number write oh no, a crash!.

 public static void main(String[] args) 
    {
          Scanner scanner = new Scanner(System.in);

          System.out.println("Tell me your age:");
          int age = scanner.nextInt();

          System.out.println("Your age is " + age);
    }

Yup. Your program just crashed. It spat out some red lines that read something like this.

 Exception in thread "main" java.util.InputMismatchException
    at java.util.Scanner.throwFor(Scanner.java:864)
    at java.util.Scanner.next(Scanner.java:1485)
    at java.util.Scanner.nextInt(Scanner.java:2117)
    at java.util.Scanner.nextInt(Scanner.java:2076)
    at com.codescrubs.Main.main(Main.java:13)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

    Process finished with exit code 1

That's an exception. Exceptions are problems that your program has experienced. They disrupt the normal flow of your program and make it crash. Reducing the amount of exceptions inside your programs is a top priority.

Sometimes you cannot help an exception because it's out of your control. You asked the user for a number, they gave you a letter. You program is about to crash. Well, you can except an exception and properly handle it. You have to catch it and handle it.

Reading the stacktrace

When your program crashes it will spit out a stacktrace - a detailed list of what broke and where.

First we get the name of the exception, it's called java.util.InputMismatchException and the name should hint you what the problem is. It's a problem with a token mismatch. We also can check the line that threw the exception and it's at java.util.Scanner.throwFor(Scanner.java:864). That's not our code, so we can't fix it.

Let's go a few lines down to where we find our code at com.codescrubs.Main.main(Main.java:13). If we check our code at line 13 we can see the offending bad code which is int age = scanner.nextInt();.

Hm... Well the stacktrace told us that we had a token mismatch at line 13. We were expecting an int and we got something else. Let's now fix our bad code.

Try catch

We can tell the compiler to try to run something, and if the application breaks we'll catch the exception and handle it.

package com.codescrubs;

// Tell the compiler where the InputMismatchException is located
import java.util.InputMismatchException;

public static void main(String[] args) 
{
     Scanner scanner = new Scanner(System.in);

     System.out.println("Tell me your age:");

     try
     { 
         int age = scanner.nextInt();
         System.out.println("Your age is " + age);
     } 
     catch (InputMismatchException exception)
     {
         System.out.println("Wrong input. Please run the program again.");
     }
 }

We use try to tell the compiler to try to run something. In our case, get the age from the user as an int. If that's successful and nothing breaks, output the age to the console. If the user inputs something that's not an int, we'll catch the exception. We want to catch a specific exception so we are going to write InputMismatchException exception inside the catch parenthesis. Make sure that you import the exception at the top of the file as well.

We can then write some code inside the catch code block to tell the user that the application broke and the cause of it. We could also prompt the user to input a new number and so forth.

If we now run our code and try to break it, we'll see "Wrong input. Please run the program again.". Our program won't crash again for typing a wrong input, it will tell just the user to try again.

Cool, we've just handled a user error, caught an exception and prevented a crash.

Why don't we put the whole program inside a try catch?

Because that wouldn't solve anything. The purpose of a try and catch block is to handle when something bad happens. We want to target very specific and very small parts of code with a try catch block, so that we can handle it as precise a possible.

Sadly, there's no magic bullet for the best way of handling exceptions. You have to ask yourself what you want to do if something in your code breaks. If you asked the user for a number and they gave you a letter, you should probably let the user try again. If you asked the user for the code for nuclear destruction and they inputted that incorrectly, well... you probably should not let the user try again.

« Previous lesson:
Getting input from the user