Checked vs Unchecked Exceptions in Java

Java has a long list of exceptions in it. The two main types of exceptions present here are checked and unchecked exceptions. Before diving deep into this topic, check out our article on “Java Exceptions” to have a basic understanding of exceptions in Java.

Cause of Exception in Java:

Exceptions occur in various instances. Here are some of the main reasons for exceptions to occur:

  • Due to mistakes by users during an input operation.
  • Syntax errors.
  • Lack of memory space.

Categories of Java exceptions:

The exceptions in Java are broadly classified into two categories:

1. JVM Exceptions: Only the JVM can throw this set of exceptions. Some of the JVM Exceptions are: ArrayOutOfBoundException, ClassCatException, NullPointerException etc.

2. Programmatic Exceptions: The exceptions that the API programmers or the applications throw explicitly are known as programmatic expressions. Examples: IllegalStateException, IllegalArgumentException.

Types of Exceptions in java:

Normally, there are two types of options namely, checked and unchecked exceptions. But according to the suggestions of Oracle, there are three types of exceptions:

  • Checked Exceptions
  • Unchecked Exceptions
  • Errors

Here, an error is also considered as one of the types of exception. These are exceptions that are irrecoverable and checked during runtime. Some of the examples are OutOfMemoryError, VirtualMachineError, etc.

Java Checked Exceptions:

The exceptions that are checked during the compile time are checked exceptions. During this time, the Java compiler ensures that the method with the error code that throws an exception also consists of a try-catch block.
In the absence of the code segment to handle them, the compiler checks if the method is declared with the throws keyword. If neither of the two cases is encountered, it gives a compilation error.

In general, the checked exceptions represent the error situations that occur outside the program’s control. This takes place when they interact with the other systems. For example, network correction errors, database errors and missing files, etc. Usually, a checked exception extends the Exception class in Java.

Examples of Java Checked Exceptions:

In the case of writing a program to read data from a file using FileReader class when the file doesn’t exist, we arrive at the FileNotFoundException.

Some of the common checked exceptions in Java are:

  • ClassNotFoundException
  • FileNotFoundException
  • InvocationTargetException
  • IOException
  • SQLException

Sample code to demonstrate java checked exception:

import java.io.File;
import java.io.FileReader;
public class CheckedExceptions
{
public static void main(String args[])
{
File file = new File("/home/firstcode/file.txt");
FileReader fileReader = new FileReader(file);
System.out.println("Success");
}
}

Output:

Exception in thread “main” java.lang.Error: Unresolved compilation problem:
Unhandled exception type FileNotFoundException
at project1/com.firstcode.exceptions.CheckedExceptions.main(CheckedExceptions.java:10)

Let us now modify the code by adding the ‘throws’ keyword with the main so that, there would be no errors.

import java.io.*;
public class CheckedExceptionsModified
{
public static void main(String args[]) throws IOException
{
File file = new File("/home/firstcode/file.txt");
FileReader fileReader = new FileReader(file);
System.out.println("Success");
}
}

Output:

Success

Let us now modify the same code by fixing it using the try-catch block.

import java.io.*;
public class FirstCodeCheckedModified2
{
public static void main(String args[])
{
FileInputStream fis = null;
try
{
fis = new FileInputStream("/home/firstcode/file.txt");
}catch(FileNotFoundException fnfe)
{
System.out.println("The file is not available at the given location");
}
int k;
try
{
while(( k = fis.read() ) != -1)
{
System.out.print((char)k);
}
fis.close();
}catch(IOException ioe)
{
System.out.println("I/O error occurred: "+ioe);
}
}
}

Output:

The file is not available at the given location
Exception in thread “main” java.lang.NullPointerException
at project1/com.firstcode.exceptions.FirstCodeCheckedModified2.main(Example.java:15)

Java Unchecked Exceptions:

The exceptions that are not caught during the compile time are known as unchecked exceptions. This type of error usually represents an incorrect programming logic in the code. They mostly do not occur due to the improper use of an API.

The compiler cannot find in advance the logical errors that occur only during the runtime. Due to this, it can’t check those errors during the compile time. This is the reason why it is called an ‘unchecked’ exception.

These exceptions are the subclasses of RuntimeException class. Some of the commonly known examples are:

  • ArithmeticException
  • ArrayStoreException
  • ClassCaseException

And to note one thing is that, the RuntimeException is itself subclass is Exception. That is, all the unchecked exception classes should implicitly be checked exceptions, but they are not.

Examples of Unexpected exceptions in Java:

For instance, when a program aims to divide a number by zero or if there are illegal arithmetic operations taking place, it throws a runtime exception. To quote another example, when we try to access the 105th element of an array whose total size is only 100, we get the ArrayIndexOutOfBounds exception. The same error occurs even if we try to access a negative index like -2.

Some of the unchecked exceptions in java are:

  • ArithmeticException
  • ArrayOutOfBoundsException
  • Empty Stack Exception
  • IllegalStateException
  • InputMismatchException
  • Missing Resource Exception
  • NoSuchElementException
  • NullPointerException
  • NumberFormaatException
  • Undeclared Throwable Exception

Sample program to illustrate the Unchecked Exception:

public class UnCheckedExceptions
{
public static void main(String args[])
{
//ArrayIndexOutOfBoundsException
int array[] = {1, 2, 3, 4, 5};
System.out.println(array[7]);
}
}

Output:

Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: Index 7 out of bounds for length 5at project1/com.firstcode.exceptions.UnCheckedExceptions.main(UnCheckedExceptions.java:8)

Comparison between Checked and Unchecked exceptions in Java:

  Java Checked Exception Java Unchecked Exception
1 These exceptions occur during compile time. These exceptions occur during the runtime.
2 Also known as a compile-time exception. Also known as run-time exceptions.
3 The role of the compiler, in this case, is to check a checked exception. The compiler does not check the unchecked exceptions.
4 We must handle these exceptions during compilation.  It is not possible to handle these exceptions during the compilation time as they are mistakes made in the program.
5 The compiler throws an error if the code does not handle the exceptions. The compiler does not throw an error if the code does not handle the unchecked exceptions.
6 They belong to the direct subclass of the exception class. These are runtime exceptions and do not come under the Exception class. They are the subclass of RuntimeException class. 
7 These exceptions occur when the chances of failure are too high. These exceptions occur due to programming mistakes.
8 The JVM has to catch and handle these exceptions. The JVM need not catch and handle these exceptions.
9 We can also create user-defined checked exceptions by extending the java.Lang.Exception class. We can create user-defined Unchecked exceptions by extending the RuntimeException class.
10 Some of the examples of Checked Exceptions are:

 ClassNotFoundException

FileNotFoundException

InterruptedException

InvocationTargetException

IOException

NoSuchFieldException

SQLException

Some of the examples of Unchecked Exceptions are:

 ArrayOutOfBoundsException

ArithmeticException

EmptyStackException

IllegalStateException

InputMismatchException

NoSuchElementException

NullPointerException

NumberFormatException

MissingResourceException

UndeclaredThrowableException

How JVM Handles an Exception:

This part of the article explains default exception handling. Once an exception is identified, an Exception object is created. Then, the object will be transferred to the JVM’s run-time system. This object includes details regarding the name, description, and the current state of the exception. When an exception occurs, various methods would need to be called, this list of methods known are Call Stack.

The actions that would take place after this are:

  • The JVM searches for the Exception Handler that contains the code to handle the exception.
  • Then, it looks for the method where the exception occurred.
  • Once the JVM encounters the required handler, it passes the exception to the handler.
  • In the other case scenario, if the JVM is unable to look for an appropriate handler, it prints a default message and
  • terminates the abnormality.

Sample code to explain Exception Handling by JVM:

package com.FirstCodeExample.exceptions;
public class FirstCodeException
{
public static void main(String args[]){
String s = null;
System.out.println(s.length());
}
}

Output:

java.lang.NullPointerException
at com.FIrstCodeExample.exceptions.exception.main(exception.java:7)
at com.FirstCodeExample.exceptions.__SHELL0.run(__SHELL0.java:6)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at bluej.runtime.ExecServer$3.lambda$run$0(ExecServer.java:849)
at bluej.runtime.ExecServer.runOnTargetThread(ExecServer.java:964)
at bluej.runtime.ExecServer$3.run(ExecServer.java:846)

How Programmer handles an exception in java:

Java consists of five keywords that programmers can use to handle exceptions. The try block in the code checks for exceptions when code with an exception is passed via it. It is followed by the throwing of exceptions into the catch block. Then, the finally block executes to perform the code given to it. To note, the throws and throw keywords are used to implement the customized exception.

Try-Catch block:

try{
    //code
}
catch(Exception e) {
    //handle exception
}

Common Exception scenarios in Java:

1. SQLException: Trying to implement SQL queries improperly leads to such exceptions.
2. IOException: In cases when the JVM fails to open the IO Stream, we will receive this exception.
3. ClassFoundException: When we attempt to access a class that is not present, the JVM throws this error.
4. ArithmeticException: Improper arithmetic calculations like “diving a number by zero” will throw this error.

Sample program to illustrate Java ArithmeticException:

package com.FirstCodeExample.exceptions;
public class ArithException
{
public static void main(String args[])
{
int n = 20/0;
System.out.println("Arithmetic Exception Encoutered: " + n);
}
}

Output:

java.lang.ArithmeticException: / by zero
at com.FirstCodeExample.exceptions.exception.main(exception.java:6)
at com.FirstCodeExample.exceptions.__SHELL0.run(__SHELL0.java:6)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at bluej.runtime.ExecServer$3.lambda$run$0(ExecServer.java:849)
at bluej.runtime.ExecServer.runOnTargetThread(ExecServer.java:964)
at bluej.runtime.ExecServer$3.run(ExecServer.java:846)

5. NumberFormatException: After declaring a variable as a string, the JVM throws this error if we try to convert it into a single digit.

Sample Program to implement Java NumberFormatException:

package com.FirstCodeExample.exceptions;
public class NumberFormatExe
{
public static void main(String args[])
{
String str= "FirstCode";
int num=Integer.parseInt(str);
System.out.println(num);
}
}

Output:

java.lang.NumberFormatException: For input string: “FirstCode”
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Integer.parseInt(Integer.java:652)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at com.DataFlair.exceptions.exception.main(exception.java:7)
at com.DataFlair.exceptions.__SHELL2.run(__SHELL2.java:6)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at bluej.runtime.ExecServer$3.lambda$run$0(ExecServer.java:849)
at bluej.runtime.ExecServer.runOnTargetThread(ExecServer.java:964)
at bluej.runtime.ExecServer$3.run(ExecServer.java:846)

6. IllegalArgumentException: passing an improper or incorrect argument to a method will lead to this error.

Sample program to implement Java IllegalArguementException:

package com.FirsrtCodeExample.exceptions;
public class IlegalArgExe
{
public static void main(String[] args)
{
Thread t1 = new Thread(new Runnable() {
public void run()
{
try {
Thread.sleep(-10);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("FirstCode");
}
});
t1.setName("Test Thread");
t1.start();
}
}

Output:

Exception in thread “Test Thread” java.lang.IllegalArgumentException: timeout value is negative
at java.base/java.lang.Thread.sleep(Native Method)
at com.FirstCodeExample.exceptions.exception$1.run(exception.java:10)
at java.base/java.lang.Thread.run(Thread.java:834)

7. IllegalStateException: Calling a method at the wrong time will lead to this error.

Sample program to implement Java IllegalStateException:

package com.FirstCodeExample.exceptions;
import java.util.ArrayList;
import java.util.ListIterator;
public class IllegalStateExe
{
public static void main(String args[]) {
ArrayList<String> list = new ArrayList<String>();
list.add("Data");
list.add("Flair");
ListIterator<String> it = list.listIterator();
it.remove();//Removing element without moving the first position.
}
}

Output:

java.lang.IllegalStateException
at java.base/java.util.ArrayList$Itr.remove(ArrayList.java:1009)
at com.FirstCodeExample.exceptions.exception.main(exception.java:11)
at com.FirstCodeExample.exceptions.__SHELL0.run(__SHELL0.java:6)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at bluej.runtime.ExecServer$3.lambda$run$0(ExecServer.java:849)at bluej.runtime.ExecServer.runOnTargetThread(ExecServer.java:964)
at bluej.runtime.ExecServer$3.run(ExecServer.java:846)

8. NullPointerException: An example of this exception would be attempting to find the length of a null value. It is well-known that null doesn’t possess a value as it allocates no memory space. Thus, in such scenarios, the NullPointerException will be thrown.

Sample code to implement Java NullPointerException:

package com.FirstCodeExample.exceptions;
public class NullPointExe
{
public static void main(String args[])
{
String str= null;
System.out.println(str.length());
}
}

Output:

java.lang.NullPointerException
at com.DataFlair.exceptions.exception.main(exception.java:7)
at com.DataFlair.exceptions.__SHELL1.run(__SHELL1.java:6)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at bluej.runtime.ExecServer$3.lambda$run$0(ExecServer.java:849)
at bluej.runtime.ExecServer.runOnTargetThread(ExecServer.java:964)
at bluej.runtime.ExecServer$3.run(ExecServer.java:846)

9. ArrayOutOfBoundException: When we try to access an index that exceeds the size of the given array, the ArrayoutOfBoundException is thrown.

Sample code to implement Java ArrayOutOfBoundException:

package com.FirstCodeExample.exceptions;
public class ArrayOutOfBoundExe
{
public static void main(String args[])
{
int num[]=new int[10];
num[20]=500;
System.out.println(num[20]);
}
}

Output

java.lang.ArrayIndexOutOfBoundsException: Index 20 out of bounds for length 10
at com.FirstCodeExample.exceptions.exception.main(exception.java:7)
at com.FirstCodeExample.exceptions.__SHELL3.run(__SHELL3.java:6)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at bluej.runtime.ExecServer$3.lambda$run$0(ExecServer.java:849)
at bluej.runtime.ExecServer.runOnTargetThread(ExecServer.java:964)
at bluej.runtime.ExecServer$3.run(ExecServer.java:846)

When to use checked and unchecked exceptions in Java:

You cannot apply to check the checked and unchecked exceptions at random instances. According to the Oracle Java Documentation, there is a guide on when to use these exceptions.

“If a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception.”

Let us now understand this with an example. Before opening a file, we can validate the input file name. in case of providing an invalid name for the input, then the checked exception can be thrown.

Here is the snippet to show it:

if (!isCorrectFileName(fileName))
{
throw new IncorrectFileNameException("File name is invalid: " + fileName );
}

When the input file name is an empty string, it means the code contains an error. In such cases, we should throw the unchecked exception. 

Here is the snippet to show it:

if (fileName == null || fileName.isEmpty())
{
throw new NullOrEmptyException("The filename is null or empty.");
}

Handling checked and Unchecked Exceptions in Java:

Here is a sample program to explain this topic clearly:

public static void main(String[] args) 
{
 try 
    {
     
Class.forName("com.art1.FirstCodeExample");
    } 
catch (ClassNotFoundException e) {
 
System.out.println("Class not found.");
 }  
 String input = null;
 input.length(); // throws an unchecked exception   
}

Program explanation:

The class com.art1.FirstCodeExample is loaded into the JVM by the method Class.forName(). In precaution that the class might not be available, the developer handles the ClassNotFoundException with the help of try-and-catch.

During the execution of the code, the forName() method might not throw a ClassNotFoundException. Yet, the developer is forced to handle this condition.

Now, let us look at the value where String is assigned to null, and the length().the input.length() invokes a NullPointerException and makes the program fail each time it executes successfully. Improper or poor programming practices will lead to such situations. Hence, it requires no exception handling.

Modern use of Java unchecked exceptions:

In situations where we are likely to obtain only fewer data recovered from checked exceptions, it is quite unproductive. It only adds unwanted lines to the code making it less readable and hard to maintain.

In recent trends, the industry moves into avoiding the extensive creation of checked exceptions in a framework or an API. Most of the frameworks capture the checked exceptions and throw them as unchecked exceptions.

Advantages of Using Java Exceptions:

The vital reason to implement exception handling is that the program functions without any unwanted interruptions. Normally, the exceptions disrupt the flow of the program and this is avoided with the help of exception handling methods.

Java Exception Handling Best Practices:

1. In situations where a method fails to fulfil its assigned task correctly, the Checked exceptions can take over. To give an example, the method prepareSystem()’s task is to pre-populate configure files.

2. It prompts the FileNotFoundException to imply that the given methods are not present in the file system.

3. We can use the Checked exceptions in case of resource errors or flow control and not while encountering programming errors. Throwing those errors would be a good choice when no method can handle those exceptions.

4. To make things easier, you can mention the exceptions next to the respected methods. for example, while declaring findProvider() method, mention the NoSuchProviderException close to it.

5. In the case of a custom exception, if it is the one that the client can easily recover from, then it should be made as a checked exception. If the client cannot recover from the exception, it should be made an unchecked exception.

6. Generally speaking, most of the applications will recover from all the exceptions including IlelgalArgumentException, NullPoinerException, and various other unchecked exceptions. The application must jump to the next task to keep up with the flow without stopping it.

7. Sometimes, the application has no other go than to shut down. This happens especially when a configuration file is missing and the application will be unable to carry out the tasks in its absence. In such cases, shutting down the application is acceptable.

Conclusion

Exceptions cause delays in a normal program. The main two types of exceptions in Java are Checked or compile-time and Unchecked or run-time exceptions. Altering the code accordingly will reduce the occurrence of errors in the program. Now you might be clear enough to differentiate between both types of exceptions in Java.

Leave a Reply

Your email address will not be published. Required fields are marked *