You are here
Home > java > Core Java >

How To Resolve Common Java Exceptions

How To Resolve Common Java ExceptionsWhile writing code, developers may encounter errors or exceptions with any programming language. These exceptions can be disappointing to deal with, but most issues can be resolved quickly and easily by having a bit of knowledge and troubleshooting. In this article, we will talk about How to resolve common Java exceptions that developers may face during the development. We will go through step-by-step solutions to fix them. If you practice applying these solutions, you can improve your Java programming skills, become a good problem resolver, and a successful developer. So let’s start and learn how to resolve common Java exceptions!

What are the general Guidelines To avoid Java Exceptions?

In order to avoid any exception, it is important to understand and follow best practices and coding guidelines. Some general guidelines include:

1) We should always validate user input before using it in our code.

2) Use try-catch, throws, throw blocks, whichever is appropriate at a particular scenario in order to avoid exceptions

3) You should have enough error handling and error messages in your code to help determine and fix issues.

4) Make sure to log the exceptions for debugging purposes. You can use logger messages to help identify the issues.

5) Follow best practices for coding to avoid exceptions, and test your code carefully.

6) Keep your API dependencies up-to-date to ensure that you are using the latest and most stable versions of libraries and frameworks.

7) Use appropriate tools and testing frameworks to identify potential issues in your code before they cause exceptions.

8) Monitor your application’s performance and logs to identify and fix any issues promptly.

9) Stay updated with the latest security best practices to ensure that your code is secure and protected from any potential attacks.

10) Document your code and its exceptions thoroughly to make it easier for other developers to understand it and maintain.

We can reduce the occurrence and effects of exceptions in our Java code by following these guidelines and applying best practices.

What are the Common Java Exceptions?

There is a long list of exceptions in Java, but some of the most common ones are:

NullPointerException 

NullPointerException is a type of RuntimeException that occurs when we attempt to use a reference variable that has a null value, that means it points to an object or variable whose value is null. This can happen when we try to call a method or access a field on an object that has not been initialized or when we pass null as a parameter to a method that doesn’t handle it.

In order to prevent it, we can check if a reference variable is null using the == operator and handle the null case properly. As an alternative, we can initialize our variables with default values wherever possible to ensure that we never encounter a null reference.

Another approach to avoid NullPointerException in Java is to use the Optional class. Optional is a container object that may or may not contain a non-null value. It is used to represent the presence or absence of a value, similar to how a null value is used to represent the absence of a value. If the programmer attempts to access the value of an Optional object that is empty, the program will not throw a NullPointerException, but instead return an empty Optional. In other words, Optional forces the programmer to handle the case where the value is absent, which helps to avoid NullPointerException.

IndexOutOfBoundsException

IndexOutOfBoundsException is a runtime exception that occurs when an index used to access an array or a collection is either negative or greater than or equal to the size of the array or collection.

To prevent this exception, we should ensure that the index used to access an array or collection is within its boundary, i.e., it should be greater than or equal to zero and less than the size of the array or collection.

ArrayIndexOutOfBoundsException

ArrayIndexOutOfBoundsException is a type of IndexOutOfBoundsException that occurs when an attempt is made to access an array at an invalid index.

In Java, the indices of an array start at 0 and end at length-1, where length is the number of elements in the array. If you try to access an element at an index outside this range, Java will throw an ArrayIndexOutOfBoundsException.

If you encounter an ArrayIndexOutOfBoundsException, you should review your code to ensure that you are using the correct indices when accessing elements in an array.

StringIndexOutOfBoundsException

StringIndexOutOfBoundsException is a type of IndexOutOfBoundsException that occurs when an attempt is made to access a character in a String at an invalid index.

In Java, the index of a String starts at 0 and ends at length()-1, where length() is the number of characters in the String. If you try to access a character at an index outside this range, you may encounter a StringIndexOutOfBoundsException.

If you encounter a StringIndexOutOfBoundsException, you should review your code to ensure that you are using the correct indices when accessing characters in a String.

ClassCastException

This occurs when we try to cast an object to a type that is not compatible with its actual type.

To resolve this, it is important to ensure that your Java program only attempts to cast objects to classes that they are instances of. You can check the type of an object using the instanceof operator before applying a cast.

IllegalArgumentException

IllegalArgumentException is a type of RuntimeException that occurs when a method is called with an illegal or improper argument. In other words, this can happen when a method is called with an argument that is outside the expected range or does not have the expected format or structure. For example, a method requires a positive number as an argument, and we are providing a negative number which is an illegal input.

If you face an IllegalArgumentException, you should review your code to ensure that you are calling methods with legal and appropriate arguments.

IllegalStateException

IllegalStateException is a type of RuntimeException that occurs when an object is in an inappropriate state for the operation that is being executed. This can take place when a method is called on an object that is not in the expected state. For example, if we create a database connection object and then close it. Now, if we attempt to create a Statement object on the closed connection, this will cause an IllegalStateException to be thrown, because the createStatement() method requires an open connection.

If you encounter an IllegalStateException, you should review your code to ensure that you are calling methods on objects that are in the appropriate state.

UnsupportedOperationException

UnsupportedOperationException is a type of RuntimeException that occurs when an unsupported operation is attempted on an object. This can happen when we call a method that is not implemented by the object, or is not supported by the object.

In order to prevent this, we should not call such operations which are not supported on objects. We should review our code to ensure that we are calling methods on objects that support the operation.

ArithmeticException

ArithmeticException is a type of RuntimeException that occurs when an arithmetic operation produces an invalid result. When we attempt an arithmetic operation with an improper or illegal argument, this exception can occur. Additionally, it can occur when an arithmetic operation results in an overflow or underflow. For example, this can occur when attempting to divide by zero or when an integer operation overflows.

To resolve this, we can perform input validation and ensure that the arguments meet the required conditions before performing the arithmetic operation.

SecurityException

As the name suggests, this occurs when a security violation happens. SecurityException is a type of RuntimeException that occurs when a security violation is detected during the execution of a program. This can happen when a program attempts to perform an operation that is not allowed by the security policy.

To address this issue, we should make sure to access resources and implement operations for which we have specific permission.

NumberFormatException

NumberFormatException is a type of RuntimeException that occurs when a method is called to convert a string into a numeric format, but the string does not have the relevant format.

To address this, we should first validate user input before trying to convert it. You should review your code to ensure that you are attempting to convert strings that have the appropriate format for the target numeric type.

InterruptedException

InterruptedException is a checked Exception that is thrown when a thread is waiting, sleeping, or blocking for some event, and that event is interrupted by another thread. This can happen when a thread is waiting for input, waiting for a lock to be released, or waiting for some other operation to complete, and another thread interrupts the waiting thread.

To address this, you can catch InterruptedException and respond by cleaning up resources, stopping the thread, or taking other appropriate action. If you encounter an InterruptedException, you should review your code to ensure that you are handling thread interruptions properly.

FileNotFoundException

FileNotFoundException is a checked Exception that is thrown when a program tries to access a file that does not exist or cannot be found at the specified location. This can happen when a file is misspelled, moved, or deleted, or even when the program does not have the necessary permissions to access the file.

To fix this, you can perform input validation and ensure that the file path is correct and the program has the necessary permissions to access the file.

IOException

IOException is a checked exception in Java that represents an error that occurred while performing input or output operations, such as reading from or writing to a file or network socket. This can happen due to multiple reasons, such as a specified file is missing or inaccessible, a network error, or insufficient permissions.

To fix this, we should take few steps such as, check the error message, handle the exception using try-catch, close resources, check permission to access the file etc.

NoSuchMethodException

NoSuchMethodException is an exception that is thrown at runtime when we try to invoke a method that does not exist in a class. This exception is generally thrown when we call a method using the Class.getMethod() or Class.getDeclaredMethod() methods and the specified method name is not found in the class or interface. It can also be thrown when we try to call a method using the java.lang.reflect.Method class and the specified method name does not exist in the object.

To avoid this exception, make sure that we are calling a valid method with the correct method signature and access specifier.

NoSuchFieldException

NoSuchFieldException is a runtime exception which occurs when we try to access a field that does not exist in a class. This exception is commonly thrown when we call a method using the Class.getField() or Class.getDeclaredField() methods and the specified field name is not found in the class or interface. Additionally, it can also be thrown when we try to access a field using the java.lang.reflect.Field class and the specified field name does not exist in the object.

To avoid this exception, make sure that you are accessing a valid field with the correct name and access modifiers. If you are accessing a private field, make sure to use the getDeclaredField() method instead of the getField() method.

IllegalAccessException

IllegalAccessException is a runtime exception that occurs when we try to access a field or method in a class, but we do not have the necessary access rights. This exception is usually thrown when we attempt to access a private field or method from outside of the class, or when we try to access a protected field or method from a class that is not a subclass of the original class. Even, it can also be thrown when we attempt to access a field or method that has been marked as inaccessible through the use of the java.lang.reflect.AccessibleObject class.

To avoid this exception, make sure that you have the necessary access rights to the field or method that you are trying to access. If the field or method is private, you may need to use reflection and set the AccessibleObject to true in order to access it. However, be careful when using reflection to access private fields or methods, as this can break encapsulation and compromise the integrity of the class.

VerifyError

VerifyError is a runtime error which is subclass of LinkageError. It occurs when the Java Virtual Machine (JVM) encounters a class file that violates certain verification rules. When a Java class is compiled, the compiler checks if the bytecode follows to certain rules and constraints, such as type safety and proper use of stack and local variables. If a class file violates these rules, the JVM will throw a VerifyError when the class is loaded and verified at runtime.

To avoid a VerifyError, make sure that your Java code follows the proper syntax and semantics of the Java language. If you encounter a VerifyError, you should review your code to ensure that it is valid and that there are no violations of the Java bytecode verification rules.

OutOfMemoryError

OutOfMemoryError is a subclass of Error, which is a type of Throwable that represents serious problems that are not recoverable at runtime. However, Java 8 includes some improvements to garbage collection and memory management, it is still possible to encounter OutOfMemoryError if our application uses too much memory or does not properly manage memory usage.

In order to avoid OutOfMemoryError, it is essential to properly manage memory utilization in your Java application. This can include using data structures and algorithms that are memory-efficient, avoiding needless object creation, and properly disposing of objects when they are no any more needed. Furthermore, you can increase the maximum heap size for the JVM by using the -Xmx flag when running your Java program.

StackOverflowError

StackOverflowError is a type of Error that occurs when the stack size required by a program exceeds the amount of memory allocated for it. This can happen when a program calls too many nested methods or when a method calls itself recursively too many times, resulting in an infinite loop.

The Java Virtual Machine (JVM) allocates a fixed amount of memory for the execution stack, which is used to keep track of method calls and local variables. When the stack overflows, the JVM throws a StackOverflowError.

In order to avoid StackOverflowError, it is important to ensure that your Java program uses recursion and method calls adequately. If you encounter a StackOverflowError, you can try increasing the stack size using the -Xss flag when running your Java program.

InvocationTargetException

InvocationTargetException is a checked exception that is thrown by Java’s reflection mechanism. It comes under the package java.lang.reflect.InvocationTargetException and is used to indicate that an exception occurred during the invocation of a method or constructor.

When a method or constructor is invoked using Java’s reflection mechanism, the invoke() method of the java.lang.reflect.Method or java.lang.reflect.Constructor class is called. If the invoked method or constructor throws an exception, the invoke() method will catch it and wrap it inside an InvocationTargetException. This exception is then thrown to the caller of the invoke() method.

To resolve an InvocationTargetException, we need to catch the InvocationTargetException, get the root cause exception using the getCause() method, handle the root cause exception appropriately. Note that the root cause exception may be a checked exception or a runtime exception, so make sure to handle it properly.

How To Resolve Common Java Exceptions With Examples?

NullPointerException

Scenario: You have a method that accesses an object which is null.

String title= null;
System.out.println(title.length()); // It will throw a NullPointerException

Solution#1: Check if the object is null before using it.

if(title!= null) {
   System.out.println(title.length());
} else {
   System.out.println("title is null");
}

Solution#2: Use Optional to avoid NullPointerException.

Optional<String> optionalTitle = Optional.ofNullable(getTitle());
if (optionalTitle.isPresent()) { 
   String title= optionalTitle.get(); 
   System.out.println("Title: " + title);
} else { 
   System.out.println("Title is not available.");
}

ArrayIndexOutOfBoundsException

Scenario: You try to access an array with an index that is outside of its boundary.

int[] numbers = {4, 5, 6};
System.out.println(numbers[3]);   // It will throw an ArrayIndexOutOfBoundsException

Solution: Check the array’s length before accessing it and ensure that you use valid indexes.

int[] numbers = {4, 5, 6};
if (numbers.length > 3) {
   System.out.println(numbers[3]);
} else {
   System.out.println("ArrayIndexOutOfBoundsException: Please use valid indexes of the Array");
}

ClassCastException

Scenario: You try to cast an object to a type that is not compatible with its actual type.

Object obj = "Java Exception";
Integer number = (Integer) obj; // It will throw a ClassCastException

Solution: Ensure that you only cast objects to types that they are compatible with.

Object obj = "Java Exception";
if(obj instanceof Integer) {
   Integer number = (Integer) obj;
   System.out.println(number);
} else {
   System.out.println("Object cannot caste to Integer");
}

IllegalArgumentException

Scenario: When you pass an illegal argument to a method.

public void printNumber(int number) {
   if(number <= 0) {
      throw new IllegalArgumentException("You cannot pass a negative number or zero");
   }
   System.out.println(number);
}

printNumber(-1); // This will throw an IllegalArgumentException

Solution: Ensure that you pass valid arguments to methods. In this case, pass a positive number.

printNumber(1); // This will print 1 successfully.

IllegalStateException

Scenario: An object is in an invalid state.

public class Bike {

   private Boolean isStarted;

   public void start() {
      if(isStarted) {
        throw new IllegalStateException("Bike is already started");
      }
      isStarted = true;
      System.out.println("Bike started");
   }
}

Bike bike= new Bike();
bike.start();
bike.start(); // This will throw an IllegalStateException as bike is already started

Solution: Ensure that you maintain the object’s state correctly.

Bike bike= new Bike();
bike.start();

UnsupportedOperationException

Scenario: If you use an operation which is not supported by an object. One of the popular examples when you use remove() operation on an immutable collection, you will observe UnsupportedOperationException.

List<String> list = Arrays.asList("Java", "Angular", "Spring");
list.add("Python"); // This will throw an UnsupportedOperationException

In the above example, since Arrays.asList() method returns an immutable list, it will not support adding or removing elements.

Solution: Ensure that you only call supported operations on objects.

List<String> list = new ArrayList<>(Arrays.asList("Java", "Angular" "Spring"));
list.add("Python");
System.out.println(list);

ArithmeticException

Scenario#1: When we attempt to divide by zero this exception occurs. However, this is the most common scenario that we learn at a very basic level.

int i = 4;
int j = 0;
int k = i/j; // This will throw an ArithmeticException: divide by zero

Solution: Handle division by zero correctly. For example, below code demonstrates the proper handling of it.

int i = 4;
int j = 0;
if(j != 0) {
    int k = i/j;
    System.out.println(k);
} else {
    System.out.println("ArithmeticException: Cannot divide by zero");
}

Scenario#2: When we try to perform an integer division operation that produces a fractional result. However, it will not through ArithmeticException, but produces an incorrect result.

int i = 10;
int j = 4;
int k = i/j; // This will not throw an ArithmeticException, but produces a wrong result

In this case, the result of the division operation is 2.5, but it will produce a result 2.

Solution: To avoid this incorrect arithmetic calculation, we can use a data type that supports fractional values, such as double, to store the result of the division operation. Here’s an example:

double i = 10;
double j = 4;
double k = (double) i/j;

IndexOutOfBoundsException

Scenario: When we try to access a collection with an index that is outside of its bounds.

List<String> list = Arrays.asList("Apple", "Papaya", "Mango");
System.out.println(list.get(3)); // It will throw an IndexOutOfBoundsException

Solution: Check the collection’s size before accessing it and ensure that you use valid indexes.

List<String> list = Arrays.asList("Apple", "Papaya", "Mango");
if (list.size() > 3) {
   System.out.println(list.get(3));
} else {
   System.out.println("You are using the Index which is out of bounds");
}

IOException

Scenario: An input/output operation fails as the file is not accessible.

try {
   File inputFile = new FileReader("pqr.txt");
   BufferedReader reader = new BufferedReader(inputFile);
   String line = reader.readLine();
   System.out.println(line);
} catch (IOException e) {
   e.printStackTrace();
}

Solution: Handle input/output errors and ensure that the resources are properly closed.

File inputFile = new File("pqr.txt");

if (!inputFile.exists() || !inputFile.canRead()) { 
 System.out.println("The input file is missing or not readable."); 
 return;
}

try {
BufferedReader reader = new BufferedReader(inputFile);
 String line = reader.readLine();
 System.out.println(line);
  reader.close();
} catch (IOException e) {
 e.printStackTrace();
}

Please note that we can alternatively use try-with-resource feature introduced in Java 7 to close the resources automatically as shown below. We can declare one or more resources in the try statement, and Java will automatically close the resources at the end of the block, whether the block completes normally or an exception is thrown.

try (BufferedReader reader = new BufferedReader(new FileReader("pqr.txt"))) {
....
} catch {
....
}

FileNotFoundException

Scenario: A file is not found at the specified location.

try {
     BufferedReader reader = new BufferedReader(new FileReader("abc.txt"));
     String line = reader.readLine();
     System.out.println(line);
     reader.close();
} catch (FileNotFoundException | IOException e) {
     System.out.println("An error has occurred while reading the file: " + e.getMessage());
} 

Solution: Ensure that the file exists and you have the appropriate permissions to access it.

try {
    File file = new File("abc.txt");
    if(!file.exists()) {
    throw new FileNotFoundException("File not found at the specified location");
    }
    BufferedReader reader = new BufferedReader(new FileReader(file));
    String line = reader.readLine();
    System.out.println(line);
    reader.close();
} catch (IOException e) {
    e.printStackTrace();
}

NoSuchMethodException

Scenario: If you try to access a method that cannot be found.

public class TestClass {
   public void sayHello() {
      System.out.println("Hello");
   }
}

TestClass obj = new TestClass();
Method method = obj.getClass().getMethod("printHello"); // This will throw a NoSuchMethodException

Solution: Ensure that the method exists and also the method name and signature are correct.

public class TestClass {
   public void sayHello() {
      System.out.println("Hello");
   }
}

TestClass  obj = new TestClass();
try {
    Method method = obj.getClass().getMethod("sayHello");
} catch (NoSuchMethodException e) {
    e.printStackTrace();
}

ConcurrentModificationException

Scenario: A collection is modified while it is being iterated over.

List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
for (String str : list) {
  list.remove(str);  // It will throw a ConcurrentModificationException
}

Solution: Use an iterator to iterate over a collection and modify it using the iterator’s methods.

List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String str = iterator.next();
    iterator.remove();
}

Till now we have covered an extensive amount of exceptions. We will add some more in the future.

Leave a Reply


Top