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?
"Hello"is created."Hello World"is created as a new String object.- The reference
strnow points to the new object.
The original "Hello" object remains unchanged.
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
StringBuilderunless thread safety is required. UseStringBufferonly in multithreaded environments.
Do Wrapper Classes Override hashCode() and equals()?
Yes.
Wrapper classes such as:
IntegerCharacterBooleanDoubleFloatLong
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:
HashMapHashSetHashtable
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:
trycatchfinallythrowthrows
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:
trycatchfinallythrowthrows
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.