Why Are Strings Immutable in Java? - Java exception handling

A String in Java is an object that is internally backed by a character array (char[]).

Since the contents of a String cannot be modified after it is created, Strings are immutable. Whenever you perform an operation that appears to modify a String, Java creates a new String object instead of changing the existing one.

Example

String str = "Hello";
str = str + " World";

What Happens?

  1. "Hello" is created.
  2. "Hello World" is created as a new String object.
  3. The reference str now points to the new object.

The original "Hello" object remains unchanged.

Advertisement

Benefits of String Immutability

  • Improves security.
  • Enables String Pool optimization.
  • Makes Strings thread-safe.
  • Allows efficient caching of hash codes.
  • Prevents accidental modification of shared objects.

StringBuffer vs StringBuilder

StringBuffer and StringBuilder are mutable string classes, meaning their contents can be modified without creating a new object.

Unlike the String class, both allow efficient string manipulation.

StringBuffer

  • Mutable.
  • Thread-safe (methods are synchronized).
  • Slightly slower because of synchronization.
  • Suitable for multithreaded applications.

StringBuilder

  • Mutable.
  • Not thread-safe.
  • Faster than StringBuffer.
  • Suitable for single-threaded applications.

String vs StringBuffer vs StringBuilder

Feature String StringBuffer StringBuilder
Mutable ❌ No ✅ Yes ✅ Yes
Thread-safe Yes (Immutable) ✅ Yes ❌ No
Performance Slow for frequent modifications Slower than StringBuilder Fastest
Best Use Read-only text Multithreaded applications Single-threaded applications

Interview Tip: Use StringBuilder unless thread safety is required. Use StringBuffer only in multithreaded environments.


Do Wrapper Classes Override hashCode() and equals()?

Yes.

Wrapper classes such as:

  • Integer
  • Character
  • Boolean
  • Double
  • Float
  • Long

override both the equals() and hashCode() methods.

This is because wrapper classes are immutable value objects.


equals() Method

The equals() method performs value-based comparison.

Two wrapper objects are considered equal if they store the same value, even if they are different objects in memory.

Example

 
Integer a = new Integer(5);
Integer b = new Integer(5);

System.out.println(a.equals(b));
 

Output

 
true
 

Although a and b are different objects, they contain the same value.


hashCode() Method

The hashCode() method is overridden so that equal objects produce the same hash code.

This is required for proper functioning of hash-based collections such as:

  • HashMap
  • HashSet
  • Hashtable

Objects with equal values generate identical hash codes, allowing efficient searching and retrieval.


Real-Life Example

Imagine two ₹10 currency notes.

Although they are different physical notes, they represent the same monetary value.

Similarly, two Integer objects containing 10 are considered equal.


Real-Time Testing Example

In automation frameworks, wrapper classes are commonly used to store:

  • Retry counts
  • Timeout values
  • Test priorities
  • Status codes

Collections such as HashSet and HashMap rely on equals() and hashCode() to correctly compare these values.


Exception Handling in Java

Exception handling is a mechanism for handling runtime errors without terminating the program unexpectedly.

It allows applications to recover from errors and continue normal execution whenever possible.


Building Blocks of Exception Handling

Java provides five main keywords for exception handling:

  • try
  • catch
  • finally
  • throw
  • throws

try Block

The try block contains code that may throw an exception.


catch Block

The catch block handles exceptions thrown inside the corresponding try block.

You can have multiple catch blocks to handle different exception types.


finally Block

The finally block always executes, regardless of whether an exception occurs.

It is commonly used for cleanup tasks such as:

  • Closing database connections.
  • Closing files.
  • Releasing system resources.

throw Keyword

The throw keyword is used to explicitly throw an exception.

Example:

 
throw new ArithmeticException("Invalid operation");
 

throws Keyword

The throws keyword declares that a method may throw one or more exceptions.

It shifts the responsibility of handling the exception to the calling method.

Example:

 
public void readFile() throws IOException {
    // code
}
 

Exception Handling Example

 
public class ExceptionExample {

    public static void main(String[] args) {

        try {

            int divideByZero = 5 / 0;

        } catch (ArithmeticException e) {

            System.out.println(
                "ArithmeticException = " + e.getMessage()
            );

        } finally {

            System.out.println(
                "This is the finally block"
            );
        }
    }
}
 

Output

 
ArithmeticException = / by zero
This is the finally block
 

Why Exception Handling Is Important

Exception handling:

  • Prevents unexpected application crashes.
  • Separates error-handling code from business logic.
  • Improves application reliability.
  • Makes debugging easier.
  • Ensures resources are released properly.

ClassNotFoundException vs NoClassDefFoundError

Both errors relate to missing classes during runtime, but they occur in different situations.


ClassNotFoundException

ClassNotFoundException is a checked exception.

It occurs when Java attempts to load a class dynamically using methods such as:

  • Class.forName()
  • ClassLoader.loadClass()

and the class cannot be found in the classpath.

Common Causes

  • Missing JAR files.
  • Incorrect classpath.
  • Class loader issues.

Since it is a checked exception, it must be handled using a try-catch block or declared with throws.


NoClassDefFoundError

NoClassDefFoundError is an Error, not an Exception.

It occurs when:

  • The class existed during compilation.
  • The class is missing at runtime.

Common Causes

  • Required JAR removed after compilation.
  • Static initialization failure.
  • Incorrect deployment.

Since it is an Error, it usually indicates a serious application problem.


ClassNotFoundException vs NoClassDefFoundError

Feature ClassNotFoundException NoClassDefFoundError
Type Checked Exception Error
When It Occurs Class cannot be loaded dynamically Class existed during compilation but is missing at runtime
Common Cause Missing JAR or incorrect classpath Missing class after compilation or initialization failure
Handling Must be handled using try-catch Indicates a serious runtime problem

Real-Life Example

ClassNotFoundException

Trying to borrow a book that never existed in the library.

NoClassDefFoundError

The book existed when the catalog was printed but was removed from the shelf before you tried to borrow it.


Real-Time Testing Example

While executing Selenium automation scripts:

  • A missing JDBC driver JAR may cause a ClassNotFoundException.
  • A dependency that was available during compilation but missing during execution may cause a NoClassDefFoundError.

FAQs

1. Why Are Strings Immutable in Java?

Strings are immutable because they are internally backed by a character array whose contents cannot be modified after the String object is created. Any modification creates a new String object.


2. What Is the Difference Between StringBuffer and StringBuilder?

Both classes create mutable strings.

  • StringBuffer is thread-safe because its methods are synchronized.
  • StringBuilder is not thread-safe but offers better performance.

3. Do Wrapper Classes Override hashCode() and equals()?

Yes.

Wrapper classes such as Integer, Character, and Boolean override both methods.

  • equals() compares values.
  • hashCode() ensures equal objects generate identical hash codes.

4. What Are the Building Blocks of Exception Handling in Java?

Java exception handling is built around:

  • try
  • catch
  • finally
  • throw
  • throws

5. What Is the Purpose of the finally Block?

The finally block always executes, whether or not an exception occurs.

It is typically used to release resources such as files, database connections, and network connections.


6. What Is the Difference Between ClassNotFoundException and NoClassDefFoundError?

  • ClassNotFoundException is a checked exception that occurs when Java cannot load a class dynamically because it is missing from the classpath.
  • NoClassDefFoundError is an Error that occurs when a class available during compilation is missing at runtime or fails during initialization.