Strings in Java – String Class, Immutable Nature, StringBuilder and StringBuffer


Table of Contents

  1. Introduction to Strings in Java
  2. The String Class
  3. String Declaration and Initialization
  4. String Immutability
  5. Common String Methods
  6. String Comparison
  7. String Concatenation and Performance
  8. StringBuilder vs StringBuffer
  9. Real-world Use Cases
  10. Summary and What’s Next

1. Introduction to Strings in Java

In Java, strings are objects that represent sequences of characters. The String class in Java is widely used for text manipulation, storing user input, file data, and more. String handling is a fundamental part of programming, and Java provides a rich set of tools to work with them effectively.

Unlike primitive types, strings in Java are objects and are part of the java.lang package, which is automatically imported.


2. The String Class

The String class in Java is final, meaning it cannot be inherited. It represents immutable character sequences, and once a String object is created, its value cannot be changed.

Internally, Java strings are backed by a character array and stored in a special area called the string constant pool, which helps in memory optimization.


3. String Declaration and Initialization

Using string literals

String name = "John";

When using string literals, Java first checks if the string already exists in the constant pool. If it does, it reuses the reference.

Using new keyword

String name = new String("John");

This creates a new object in the heap, even if the same string exists in the pool.


4. String Immutability

Java strings are immutable, meaning once created, their values cannot be modified.

Example:

String str = "Hello";
str.concat(" World");
System.out.println(str); // Outputs: Hello

Although concat is called, the original string remains unchanged. This behavior improves security and caching but can lead to performance overhead in certain scenarios.

Immutability is one reason strings are safe to use in multithreaded environments without synchronization.


5. Common String Methods

Java provides numerous methods in the String class for various operations:

  • length(): Returns the number of characters
  • charAt(int index): Returns the character at a specified index
  • substring(int beginIndex, int endIndex): Extracts a portion of the string
  • toLowerCase(), toUpperCase(): Changes case
  • trim(): Removes leading and trailing whitespaces
  • equals(), equalsIgnoreCase(): Compares two strings
  • indexOf(), lastIndexOf(): Searches for characters or substrings
  • replace(): Replaces characters or substrings

Example:

String str = "  Java Programming  ";
System.out.println(str.trim().toUpperCase()); // Output: JAVA PROGRAMMING

6. String Comparison

Using ==

Compares reference, not actual content.

String a = "Java";
String b = "Java";
System.out.println(a == b); // true, same reference from pool

String c = new String("Java");
System.out.println(a == c); // false, different objects

Using equals()

Compares content.

System.out.println(a.equals(c)); // true

Using compareTo()

Lexicographically compares two strings.

System.out.println("apple".compareTo("banana")); // Negative value

7. String Concatenation and Performance

Strings can be concatenated using + or concat().

String result = "Hello " + "World";

However, since strings are immutable, repeated concatenation creates multiple intermediate objects, which can degrade performance in large loops.

Inefficient example:

String result = "";
for (int i = 0; i < 1000; i++) {
result += i;
}

Each + creates a new string, leading to O(n^2) complexity.


8. StringBuilder vs StringBuffer

To avoid inefficiencies of immutable strings in repetitive operations, Java provides:

StringBuilder

  • Mutable, not thread-safe
  • Better for single-threaded scenarios
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");
System.out.println(sb.toString()); // Output: Hello World

StringBuffer

  • Mutable, thread-safe (synchronized)
  • Better for multithreaded environments
StringBuffer sbf = new StringBuffer("Java");
sbf.append(" Rocks");
System.out.println(sbf); // Output: Java Rocks
FeatureStringStringBuilderStringBuffer
MutabilityImmutableMutableMutable
Thread-safeYesNoYes
PerformanceSlow for loopsFastSlower than SB

9. Real-world Use Cases

Parsing user input

Scanner sc = new Scanner(System.in);
String input = sc.nextLine().trim();
if (input.equalsIgnoreCase("yes")) {
System.out.println("Confirmed");
}

Constructing a URL

StringBuilder url = new StringBuilder("https://example.com/");
url.append("user/").append("123");
System.out.println(url.toString());

Logging

Strings are often used to log system output or build dynamic messages.

String msg = String.format("User %s has logged in at %s", username, loginTime);

10. Summary and What’s Next

In this module, we covered:

  • How strings work in Java and their immutable nature
  • How to declare, initialize, and manipulate strings
  • Efficient string handling using StringBuilder and StringBuffer
  • Key methods for comparing, transforming, and parsing strings
  • Use cases and performance considerations

Mastering strings is vital because they appear in nearly every real-world Java application, whether you’re handling input, processing text, or working with APIs.