Visit Sponsor

Written by 1:05 pm Core Java

Java String Tutorial – Comprehensive Guide with Examples

In Java, the String class is one of the most frequently used and fundamental building blocks of application logic. A String represents an immutable sequence of characters and provides a rich API for manipulation, transformation, comparison, and formatting.

This tutorial explains Strings in depth from creation and immutability to performance considerations and best practices to help you write robust, efficient Java code.

What Is a Java String?

A String in Java is an object that encapsulates a sequence of characters. It is defined by the java.lang.String class, which is immutable — once created, its value cannot be changed.

This immutability enables:

  • Security (no unexpected modifications)
  • Safe caching in the String pool
  • Efficient sharing across threads

Creating Java Strings

You can create strings in two ways:

String Literal

A string literal is created and stored in the String pool:

String s1 = "Hello";
String s2 = "Hello";

Both s1 and s2 refer to the same object in the String pool.

Using the String Constructor

String s3 = new String("Hello");

This creates a new object on the heap even if an equivalent literal exists.

String Immutability Explained

Once a String object is created, it cannot be modified. Any “modification” results in a new String object.

String s = "Hello";
s = s.concat(" World");

Here, "Hello" remains intact, and a new string "Hello World" is created. The original string stays unchanged.

String Pool and Memory Management

The String pool (internal memory for literals) improves performance and saves memory.

String a = "Tech";
String b = "Tech";

Both point to the same memory location. But:

String c = new String("Tech");

Creates a new object outside the pool.

Use intern() to move a heap object to the pool:

String d = new String("Tech").intern();

Now d references the pooled string.

Comparing Strings

Using ==

Checks reference equality, not content equality:

s1 == s2  // true for pooled literals
s1 == s3  // false for new String(...)

Using equals()

Compares actual content:

s1.equals(s3)  // true

Using equalsIgnoreCase()

Ignores case differences:

"name".equalsIgnoreCase("NAME")  // true

Common String Methods

Java’s String API is extensive. Here are frequently used methods:

Length and Char Access

int len = s.length();
char ch = s.charAt(2);

Substring Extraction

String sub = s.substring(0, 3);

Case Transformations

String upper = s.toUpperCase();
String lower = s.toLowerCase();

Searching and Matching

int index = s.indexOf("lo");
boolean found = s.contains("He");

Replacement

String replaced = s.replace("a", "b");

Splitting and Joining

Splitting

String[] parts = "a,b,c".split(",");

Joining

String joined = String.join("-", "a", "b", "c");

Formatting Strings

Use format() for structured output:

String msg = String.format("User %s has %d points", "Alice", 42);

This is cleaner than concatenation for complex output.

Immutable vs Mutable Alternatives

Since Strings are immutable, modifications can lead to excessive allocations in loops.

StringBuilder

StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" World");
String result = sb.toString();

Use StringBuilder when building strings with many append operations.

Performance Considerations

Immutability ensures safety and pooling benefits, but inefficient use can impact performance:

  • Avoid repeated concatenations inside loops using +
  • Prefer StringBuilder for dynamic text creation
  • Use intern() only when needed (pool overhead)

Example of inefficient concatenation:

String result = "";
for (String s : list) {
    result += s;  // Creates multiple intermediate Strings
}

More efficient:

StringBuilder sb = new StringBuilder();
for (String s : list) {
    sb.append(s);
}
String result = sb.toString();

Converting Between String and Primitive Types

Primitives to String

String s = String.valueOf(123);

String to Primitives

int i = Integer.parseInt("42");
double d = Double.parseDouble("3.14");

Handle potential NumberFormatException.

Unicode and Encoding

Strings represent text as Unicode sequences. Be mindful when converting byte streams:

byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
String restored = new String(bytes, StandardCharsets.UTF_8);

Always specify character sets to avoid platform default pitfalls.

Regular Expressions with String

Use matches() and replaceAll() for regex patterns:

boolean isMatch = "abc123".matches("\\w+");
String cleaned = s.replaceAll("[^0-9]", "");

Common String Mistakes

  • Using == for content comparison
  • Concatenating inside hot loops
  • Ignoring null checks before calling methods

Always validate input and prefer safe comparison:

"constant".equals(variable);

Best Practices (Senior Engineering Insight)

  • Prefer StringBuilder for dynamic text construction
  • Use String constants and pooling to reduce memory footprint
  • Avoid null pointer by checking inputs before calling methods
  • Leverage built-in methods instead of manual loops

These practices lead to robust, maintainable code.

Summary

Java Strings are fundamental and versatile. Understanding creation, immutability, comparison, transformations, and performance is essential for writing efficient Java applications. This guide covered creation patterns, comparisons, common methods, memory considerations, and best practices to help you master Java text handling.

Visited 6 times, 1 visit(s) today
Close