Historical Context & Motivation
Almost every program you have ever used — from social media apps to video games — needs to handle text. Early computers stored characters as raw numbers, and programmers had to manually track where one piece of text ended and the next began. Languages like C required developers to manage memory for character arrays by hand, which led to countless bugs and security flaws. Java was designed from the start to make working with text safer and easier by introducing the String class as a core part of the language.
The central question this lesson addresses is straightforward but essential: How do you create text values in Java, and how do you combine them to produce useful output? Understanding string creation and concatenation is the foundation for everything from printing messages to building file paths and formatting user interfaces.
Core Principles & Definitions
Before you write your first line of string code, you need to understand a few foundational ideas that make Java strings different from primitive types like int or double. These principles will help you avoid common mistakes and write cleaner code.
String Is a Reference Type
int, which store their value directly.Strings Are Immutable
String Literal Pool
Concatenation with +
+ operator is overloaded for strings. When at least one operand is a String, Java converts the other operand to a String and joins them together into a new String.The concat() Method
+, Java provides the .concat() method on String objects. It appends one string to the end of another and returns a new String, behaving much like +.Visual Explanation — String Creation in Memory
The diagram below illustrates what happens in memory when you create strings using string literals versus the new keyword. Understanding this distinction helps explain why == behaves differently than you might expect when comparing strings.
s1 and s2 share the same object in the String Pool because they were created with identical literals. Variable s3 uses new, which always allocates a separate object on the heap, even if the text matches.Notice that s1 == s2 returns true because both references point to the exact same object in the pool. However, s1 == s3 returns false because s3 points to a different object, even though the text content is identical. This is why you should almost always use .equals() to compare string content, not ==.
How Concatenation Works Under the Hood
When you write "Hello" + " World", the Java compiler translates that + into a sequence of operations that builds a new String. Since strings are immutable, every concatenation allocates a new object. Understanding the cost of this process helps you write efficient code.
The + Operator Translation
In modern Java (version 9+), the compiler transforms + concatenation into a call to invokedynamic, which the JVM optimizes at runtime. In earlier versions, the compiler would create a StringBuilder behind the scenes. Either way, the principle is the same: the JVM creates a temporary buffer, copies both strings into it, and produces a single new String object.
StringBuilder reduces this to O(n).Three Ways to Concatenate
| Technique | Syntax Example | Best For |
|---|---|---|
+ operator | "Hi" + " " + name | Simple, one-time concatenations of a few strings |
.concat() method | "Hi".concat(" ").concat(name) | Chaining two strings when you want explicit method calls |
StringBuilder | sb.append("Hi").append(name) | Loops or building long strings from many pieces |
Automatic Type Conversion
When you concatenate a non-string value with a String, Java automatically calls String.valueOf() on the non-string operand. For example, "Score: " + 100 converts the integer 100 to the string "100" and then joins them to produce "Score: 100". This automatic type conversion works for all primitive types and objects (via their toString() method).
1 + 2 + " cats" produces "3 cats" because 1 + 2 is evaluated as integer addition first. But "cats " + 1 + 2 produces "cats 12" because once a String is involved, subsequent + operations become string concatenation, evaluated left to right.Approaches to String Building
Java gives you several tools for building strings, and choosing the right one depends on the situation. The diagram below compares three common approaches side by side, showing how each handles a loop that builds a greeting from an array of names.
+ in a loop creates a new String object on every iteration, leading to O(n²) time. StringBuilder and String.join() both run in O(n) time by reusing a single internal buffer.For simple cases like System.out.println("Name: " + firstName + " " + lastName), the + operator is perfectly fine and the most readable option. The performance difference only matters when you are concatenating inside a loop that may run hundreds or thousands of times. In those situations, reach for StringBuilder or String.join().
Worked Example — Building a Greeting Message
Let's trace through a complete example that creates strings, concatenates them, and prints the result. We will build a personalized greeting that includes a user's name and their score on a quiz.
String firstName = "Alice";
String lastName = "Chen";
int score = 87;
Both firstName and lastName point to String objects in the String Pool.firstName → "Alice", lastName → "Chen", score → 87String fullName = firstName + " " + lastName;
Java evaluates left to right: first "Alice" + " " produces "Alice ", then "Alice " + "Chen" produces the final result.fullName → "Alice Chen"String message = "Great job, " + fullName + "! You scored " + score + "/100.";
When Java reaches + score, it automatically converts the integer 87 to the String "87" before concatenating.message → "Great job, Alice Chen! You scored 87/100."System.out.println(message);
This prints the complete string to the console.String.format() for more readable formatting: String.format("Great job, %s! You scored %d/100.", fullName, score). This approach uses placeholders (%s for strings, %d for integers) and is especially useful when you have many values to insert.Strengths & Limitations of Each Approach
Each concatenation technique has trade-offs. The table below summarizes when to reach for each tool, so you can make smart choices in your programs.
| Technique | Strengths | Limitations |
|---|---|---|
+ operator | Easy to read, built into the language, handles automatic type conversion | Creates new String objects each time; slow in loops with many iterations |
.concat() | Explicit and clear; slightly faster than + for two strings | Does not auto-convert non-string types; throws NullPointerException if called on null |
StringBuilder | Very fast for building strings in loops; mutable internal buffer avoids creating extra objects | More verbose syntax; not thread-safe (use StringBuffer if threads are a concern) |
String.format() | Great readability for complex templates; supports number formatting and padding | Slower than + or StringBuilder; requires learning format specifiers |
String.join() | Perfect for joining arrays/lists with a delimiter; clean one-liner | Only works with CharSequence types; less flexible for complex patterns |
+ is like a screwdriver — perfect for hanging a single picture frame. A StringBuilder is like a power drill — overkill for one screw, but essential when you're assembling a bookshelf with dozens of screws. Match the tool to the job.Connection to Advanced String Topics
The concepts you have learned here — creating strings and concatenating them — form the foundation for more advanced string manipulation you will encounter as you continue studying Java. Let's preview how these basics connect to topics you may explore next.
| What You Learned Today | What Comes Next |
|---|---|
Creating strings with literals and new | String methods like .substring(), .charAt(), .indexOf() for searching and slicing |
Comparing with .equals() instead of == | Case-insensitive comparison with .equalsIgnoreCase() and pattern matching with regular expressions |
Concatenation with + and StringBuilder | Text blocks (Java 13+) for multi-line strings and String.format() for template-based output |
| Immutability of strings | Understanding why immutability makes strings safe to share across threads and use as HashMap keys |
As you grow as a programmer, you will also learn about regular expressions, which let you search for patterns in strings (like finding all email addresses in a document), and character encoding (like UTF-8 and Unicode), which determines how characters from every language in the world are stored in memory. For now, the ability to create and concatenate strings gives you the tools to produce meaningful program output, which is the starting point for nearly every application.
Practice Problems
String s = "Hi"; s = s + "!";?int a = 3;
int b = 5;
System.out.println("Sum: " + a + b);
System.out.println("Sum: " + (a + b));StringBuilder so it runs efficiently:
String result = "";
for (int i = 0; i < 1000; i++) {
result = result + i + ", ";
}
Explain why your version is faster."Alice: A\nBob: B+\nCarla: A-".
String[] names = {"Alice", "Bob", "Carla"};
String[] grades = {"A", "B+", "A-"};
Use the most appropriate concatenation technique and justify your choice.result1 == result2 evaluates to true or false. Explain your reasoning using what you know about the String Pool and immutability.
String result1 = "Hello" + " World";
String result2 = "Hello World";
Now consider a variation:
String part = " World";
String result3 = "Hello" + part;
Does result2 == result3 evaluate to true or false? Why?Lesson Summary
In Java, a String is a reference type that represents a sequence of characters. You can create strings using string literals (double-quoted text stored in the String Pool) or the new keyword (which always creates a separate object on the heap). Strings are immutable — once created, their contents cannot be changed. Every apparent modification produces a new String object.
To combine strings, you can use the + operator for simple cases, the .concat() method for explicit method-style joining, or StringBuilder for efficient concatenation inside loops. The + operator automatically converts non-string values like integers to strings, but be mindful of left-to-right evaluation order — use parentheses when you need arithmetic before concatenation. Always compare string contents with .equals(), never with ==.