Strings in Java
String is an immutable object with a shared literal pool, and both facts explain how comparison, concatenation and performance behave.
-
Java Basics
- Introduction to Java
- Setting Up Java and Writing Your First Program
- Variables, Data Types and Literals in Java
- Type Casting and Type Conversion in Java
- Operators and Expressions in Java
- Input and Output in Java
- Comments, Keywords and Naming Conventions in Java
- Control Flow in Java: if, else and switch
- Loops in Java: for, while and do-while
- Methods
- Arrays and Strings
-
OOP
- Classes and Objects in Java
- Constructors in Java
- The this Keyword in Java
- The static Keyword in Java
- Encapsulation in Java
- Access Modifiers in Java
- Inheritance in Java
- Method Overriding and super in Java
- Polymorphism in Java
- Abstraction, Abstract Classes and Interfaces in Java
- Composition, Aggregation and Association in Java
- The Object Lifecycle in Java
- Core Java
- Exception Handling
-
Collections
- The Java Collections Framework
- List in Java: ArrayList, LinkedList, Vector and Stack
- Set in Java: HashSet, LinkedHashSet and TreeSet
- Map in Java: HashMap, LinkedHashMap and TreeMap
- How HashMap Works Internally in Java
- Queue and Deque in Java: ArrayDeque and PriorityQueue
- Iterators in Java
- Comparable and Comparator in Java
- Collections Utilities and Choosing the Right Collection
- Generics
- Java 8+
- Stream API
- Date and Time
- File and I/O
-
Multithreading
- Threads in Java: Processes, Runnable and Thread
- Thread Lifecycle in Java
- Synchronization in Java: synchronized and volatile
- Locks and Atomic Classes in Java
- Race Conditions and Deadlocks in Java
- The Executor Framework and Thread Pools in Java
- Future and CompletableFuture in Java
- Concurrent Collections in Java
- The Java Memory Model
- JVM and Memory
- Advanced Java
- Networking
- JDBC
- Testing
Definition
A String is an object representing a sequence of characters. It is a reference type, not a primitive, and it is immutable: once created, the characters it holds can never change.
Creating strings
String a = "Java"; // literal, uses the string pool
String b = new String("Java"); // explicitly a new object, avoid this
String c = String.valueOf(2026); // "2026"
String d = "Ja" + "va"; // folded to a literal at compile timeImmutability
String name = "chennai";
name.toUpperCase(); // result discarded, name unchanged
System.out.println(name); // chennai
name = name.toUpperCase(); // rebinding the variable is what works
System.out.println(name); // CHENNAIEvery method that appears to modify a string in fact returns a new one. Ignoring the return value is one of the most common early mistakes in Java.
Why immutability was chosen
- Safe sharing. Many references can point at one string with no risk, including across threads.
- Reliable hash codes. The hash cannot drift, which makes strings dependable map keys.
- Pooling becomes possible. Identical literals can be shared only because nobody can change them.
- Security. A file path or connection string cannot be altered after it has been validated.
The string pool
String a = "Java";
String b = "Java";
String c = new String("Java");
System.out.println(a == b); // true - the same pooled object
System.out.println(a == c); // false - c is a distinct object
System.out.println(a.equals(c)); // true - same characters
System.out.println(a == c.intern()); // true - intern returns the pooled instanceString literals are stored in a shared area called the string pool, which lives in the heap. Two identical literals therefore refer to one object. new String("Java") deliberately bypasses the pool and creates a second object, which is why it is almost never useful.
Compare strings withequals, never with==. Code that seems to work with==is relying on pooling, and it will fail the moment the string arrives from input, a file or a database.
Common operations
String text = " Java Programming ";
System.out.println(text.length()); // 21
System.out.println(text.trim()); // removes ASCII whitespace
System.out.println(text.strip()); // Unicode aware, preferred
System.out.println(text.isBlank()); // false
System.out.println(text.strip().charAt(0)); // J
System.out.println(text.indexOf("Program")); // 7
System.out.println(text.contains("Java")); // true
System.out.println(text.strip().substring(5)); // Programming
System.out.println(text.replace("Java", "Core"));
System.out.println("a,b,,c".split(",").length); // 4
System.out.println(String.join("-", "x", "y")); // x-y
System.out.println("ab".repeat(3)); // ababab
System.out.println(" Hi ".strip().toLowerCase());Comparison methods
| Method | Use for |
|---|---|
equals | Exact content equality |
equalsIgnoreCase | Case insensitive equality |
compareTo | Ordering, returns negative, zero or positive |
isEmpty | Length is zero |
isBlank | Empty or whitespace only, since Java 11 |
Concatenation and performance
// Poor inside a loop: each pass builds a new String and copies everything
String report = "";
for (String line : lines) {
report += line; // quadratic work
}
// Correct
StringBuilder builder = new StringBuilder();
for (String line : lines) {
builder.append(line);
}
String report = builder.toString();A single expression such as "a" + b + "c" is fine; the compiler builds it efficiently. The problem is repeated concatenation across loop iterations, where a new object is created every time.
Text blocks
String query = """
SELECT id, title
FROM notes
WHERE status = 'published'
""";Since Java 15 a text block preserves line breaks and strips the common leading indentation, which keeps embedded text readable.
Formatting
String line = String.format("%-10s %5.2f", "Total", 249.5);
String same = "%-10s %5.2f".formatted("Total", 249.5); // Java 15 and laterCommon mistakes
- Comparing with
==and being misled by pooling during testing. - Calling a method such as
replaceand discarding the result. - Building strings by concatenation inside a loop.
- Using
new String("..."), which allocates without benefit. - Assuming
length()counts visible characters. It counts UTF-16 code units, so characters outside the basic plane count as two. - Calling a method on a string that may be
null. Writing"active".equals(status)instead ofstatus.equals("active")avoids it.
Best practices
- Use
equalsfor comparison andcompareTofor ordering. - Prefer
stripovertrim, andisBlankover a length check. - Use
StringBuilderfor repeated appends and text blocks for multi line content. - Keep the constant on the left when comparing against a literal.
- Do not put passwords in a
Stringif they must be cleared from memory; achar[]can be overwritten.
Practice
- Predict each line of output in the pool example, then change
cto a literal and predict again. - Write a method that reports whether a string is a palindrome, ignoring case and spaces.
- Why does
"a,b,,c".split(",")give four elements while"a,b,c,,".split(",")gives three? - Count the occurrences of a word in a sentence without using a regular expression.
- Explain why building a 10000 line report with
+=is slow, in terms of objects created.
Conclusion
Strings are immutable objects with a shared pool of literals. Compare with equals, remember that every method returns a new string, and switch to StringBuilder the moment you are appending in a loop.