The String.concat() method concatenates a specified string to the end of the invoking string, returning a new String object.
Strict Type Safety & Zero-Length Optimization: Unlike the + operator which allows mixed data types, concat() strictly accepts only another String. If an empty string "" is appended, Java returns the original reference (this) directly without heap allocation. To join collections with a delimiter, explore String.join(). For trimming whitespace before joining, see trim(), or measure length with length().
The concat() method is defined in java.lang.String:
// Formal signature of String.concat() in java.lang.String
public String concat(String str)
| Signature Element | Type | Operational Property |
|---|---|---|
str |
String |
The string to append to the end of this string (cannot be null). |
| Return Value | String |
A new concatenated String, or this if str.length() == 0. |
| Exception | Runtime | Throws NullPointerException if the argument str is null. |
Appending one string directly onto the trailing end of another:
String greeting = "Welcome to ";
String destination = "plus2net";
// Joins destination to the end of greeting
String message = greeting.concat(destination);
System.out.println(message); // Welcome to plus2netTerminal Output:
Welcome to plus2net
Because each invocation returns a new String, calls can be chained sequentially to build longer tokens:
String base = "https: // ";
String fullUrl = base.concat("www.")
.concat("plus2net.")
.concat("com");
System.out.println("Constructed URL: " + fullUrl);Terminal Output:
Constructed URL: https://www.plus2net.com
Because strings are immutable, calling concat() never alters the calling variable. You must capture or reassign the result:
String title = "Java";
// WRONG: Original string is immutable and unchanged
title.concat(" Tutorial");
System.out.println("Uncaptured: " + title); // Java
// CORRECT: Reassign or capture the returned String instance
title = title.concat(" Tutorial");
System.out.println("Captured: " + title); // Java TutorialTerminal Output:
Uncaptured: Java
Captured: Java Tutorial
Choosing the right concatenation strategy depends on context and performance requirements:
| Technique | Accepted Types | Null Behavior | Primary Use Case |
|---|---|---|---|
s1.concat(s2) |
Strictly String only |
Throws NullPointerException |
Joining exactly two non-null strings cleanly. |
s1 + s2 |
Any type (numbers, objects, primitives) | Converts null to "null" |
General application code & log messages. |
StringBuilder |
Any type via append() |
Appends literal "null" |
Loops, bulk transformations, performance-critical paths. |
A critical behavioral difference is how null values are handled. concat() crashes on null, while + silently converts null to text:
String prefix = "User ID: ";
String id = null;
// RISKY: concat() on null argument throws NullPointerException
try {
System.out.println(prefix.concat(id));
} catch (NullPointerException e) {
System.out.println("Caught NullPointerException on concat(null)!");
}
// Contrast with '+' operator: converts null to literal "null" string
System.out.println("Using '+' operator: " + (prefix + id));Terminal Output:
Caught NullPointerException on concat(null)!
Using '+' operator: User ID: null
Calling concat() inside a loop allocates a new string on every iteration, leading to quadratic memory overhead. Always use StringBuilder in loops:
// 1. AVOID IN LOOPS: concat() creates O(N^2) temporary String objects
String slow = "";
for (int i = 1; i <= 5; i++) {
slow = slow.concat(String.valueOf(i)).concat(" ");
}
System.out.println("concat() in loop: " + slow);
// 2. RECOMMENDED IN LOOPS: StringBuilder appends in amortized O(1) time
StringBuilder fast = new StringBuilder();
for (int i = 1; i <= 5; i++) {
fast.append(i).append(" ");
}
System.out.println("StringBuilder in loop: " + fast.toString());Terminal Output:
concat() in loop: 1 2 3 4 5
StringBuilder in loop: 1 2 3 4 5
Assembling directory paths and file names with guaranteed slash delimiters:
public class FilePathBuilder {
public static String buildPath(String directory, String filename) {
if (directory == null || filename == null) return "";
if (!directory.endsWith("/")) {
directory = directory.concat("/");
}
return directory.concat(filename);
}
public static void main(String[] args) {
System.out.println(buildPath("/var/log", "app.log")); // /var/log/app.log
System.out.println(buildPath("/var/log/", "app.log")); // /var/log/app.log
}
}Terminal Output:
/var/log/app.log
/var/log/app.log
Cleanly formatting first and last names without extraneous double spaces:
public class NameFormatter {
public static String formatFullName(String first, String last) {
String f = (first != null) ? first.trim() : "";
String l = (last != null) ? last.trim() : "";
if (f.isEmpty()) return l;
if (l.isEmpty()) return f;
return f.concat(" ").concat(l);
}
public static void main(String[] args) {
System.out.println("Full Name: [" + formatFullName(" John ", " Doe ") + "]");
}
}Terminal Output:
Full Name: [John Doe]
Trying to write str.concat(42) or str.concat(true) fails compilation. Unlike the + operator, concat() strictly demands a String parameter. Convert with String.valueOf(42) first.
Passing null as the argument throws an immediate NullPointerException. Guard variables before calling concat().
You can compile and run this complete verification class locally in any Java IDE or environment:
public class StringConcatFullDemo {
public static void main(String[] args) {
String s1 = "plus2net";
// 1. Basic concatenation
String joined = s1.concat(".com");
if (joined.equals("plus2net.com")) {
System.out.println("Check 1 Passed: Basic string concatenation verified.");
}
// 2. Concatenating empty string returns exact same object reference
String same = s1.concat("");
if (same == s1) {
System.out.println("Check 2 Passed: Concatenating empty string returned same instance.");
}
// 3. Chained concatenation
String chained = "A".concat("B").concat("C");
if (chained.equals("ABC")) {
System.out.println("Check 3 Passed: Chained concatenation evaluated cleanly.");
}
System.out.println("All String.concat() unit tests passed successfully!");
}
}Terminal Output:
Check 1 Passed: Basic string concatenation verified.
Check 2 Passed: Concatenating empty string returned same instance.
Check 3 Passed: Chained concatenation evaluated cleanly.
All String.concat() unit tests passed successfully!
Java optimizes by checking if (str.length() == 0) return this;. It returns the exact same string object reference without allocating any new memory.
For concatenating exactly two strings, concat() is slightly faster because it allocates a new char array directly without compiler StringBuilder overhead. For multiple tokens, + or StringBuilder is better.
Use Java 8's built-in String.join(delimiter, elements) or StringJoiner.
No. concat() strictly accepts a String. Pass the character as a string (str.concat("!")) or convert with Character.toString(ch).
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.