In Java, checked exceptions are checked at the compile-time while unchecked exceptions are checked at the run-time

You have to handle checked exceptions by using try-catch or propagate them to the outside via declaring the throws clause on methods or constructors, otherwise, the program will not compile. On the other hand, Java doesn't force you to do that with unchecked exceptions

Exception are based classes of checked exceptions while Error and RuntimeException are based classes of unchecked exceptions

Let walk through this guide to explore them in more details

Checked exceptions are checked at compile time

In Java, Exception class and subclasses that are not also subclasses of RuntimeException are checked exceptions. Some instances of built-in checked exceptions are IOException and SQLException. You can create your own exception classes by extending the Exception

Checked Exceptions are checked at compile time. Your program can not compile if you don't try-catch or throws them

The following example handles IOException by using try-catch

public void tryCatchException() {  
    try {
        Files.readAllLines(Path.of("test.txt"));
    } catch (IOException e) {
        System.out.println(e);
    }
}

The following example propagates IOException to the outside by using the throws clause on the method declaration

public void throwsException() throws IOException {  
    Files.readAllLines(Path.of("test.txt"));
}

Unchecked exceptions are unchecked at compile-time but run-time

Error, RuntimeException and their subclasses are unchecked exceptions

Error and its subclasses are used to indicate unrecoverable and serious problems that you should not try-catch or throws. Some instances of built-in Error are StackOverflowError and OutOfMemoryError

RuntimeException and its subclasses can be recovered, you can try-catch or throws but Java doesn't force you to do that. Some instances of built-in RuntimeException are IllegalArgumentException and NumberFormatException

The following example handles NumberFormatException by using try-catch

public void tryCatchRuntimeException() {  
    try {
        Integer.parseInt("s");
    } catch (NumberFormatException e) {
        System.out.println(e);
    }
}

The following example propagates NumberFormatException to the outside by using the throws clause on the method declaration

public void throwsRuntimeException() throws NumberFormatException {  
    Integer.parseInt("s");
}

Conclusion

In this article, we learned about the difference between checked and unchecked exceptions. You can find the full source code as below