How to Reverse a String in Java: 4 Methods Explained
Reverse a Java string with StringBuilder, a loop, or a character array. Compare four methods and understand Unicode, empty strings, and null handling.
If you want to know how to reverse a string in Java, the usual answer is to create a StringBuilder, call reverse(), and convert the result back to a String. That is a good default, but the right solution also depends on what you mean by a “character”: a UTF-16 code unit, a Unicode code point, or a whole visible symbol.
This guide starts with the shortest practical solution, then shows three alternatives, explains when each is useful, and gives you edge cases to check before using the code with real text. The examples use standard Java APIs and do not require an external library.
Quick answer: use StringBuilder.reverse()
For an ordinary non-null string, use this expression:
String text = "Hello Java";
String reversed = new StringBuilder(text).reverse().toString();
System.out.println(reversed); // avaJ olleH
The expression has three steps. The constructor copies the input into a mutable builder. The reverse() call changes the order inside that builder. Finally, toString() returns the result as a String.
The original variable still refers to "Hello Java". Java String values are immutable, so this operation does not modify the original string. You must store or use the returned result. The Oracle String documentation describes both string immutability and the UTF-16 representation used by Java.
If you just need to reverse a short sample once, rather than write application code, try the online Text Reverser. For an application or programming exercise, use a Java method with a clearly defined input contract.
Which reversal method should you choose?
- For a concise, general-purpose solution: use StringBuilder.reverse(). It preserves valid surrogate pairs but not every multi-code-point visible character.
- To practise a backward loop without reverse(): append charAt() values to a builder. This works on UTF-16 code units and can split surrogate pairs.
- To demonstrate a two-pointer algorithm: swap entries in a char array. A String-to-String method still requires new storage and has the same UTF-16 limitation.
- To reverse Unicode code points explicitly: use codePoints() and appendCodePoint(). This keeps valid supplementary code points intact but still separates some combining sequences and complex emoji.
- To keep user-perceived characters together: reverse grapheme clusters using suitable Unicode-aware segmentation.
All four code examples below accept an empty string. They expect non-null input unless the method explicitly says otherwise. Decide whether your application should reject null, preserve it, or apply some other documented policy; do not let that choice happen accidentally.
Method 1: a reusable StringBuilder solution
Here is a complete program you can save as ReverseStringDemo.java:
public class ReverseStringDemo {
public static String reverse(String text) {
return new StringBuilder(text).reverse().toString();
}
public static void main(String[] args) {
String original = "Java";
String reversed = reverse(original);
System.out.println(original); // Java
System.out.println(reversed); // avaJ
System.out.println(reverse("")); // empty line
System.out.println(reverse("racecar")); // racecar
}
}
With a JDK installed, compile and run it from the folder containing the file:
javac ReverseStringDemo.java
java ReverseStringDemo
For most straightforward string-reversal tasks, this is the clearest implementation. It avoids unnecessary dependencies and makes the operation immediately recognisable to another Java developer. The amount of work grows linearly with the input length: O(n) time, with O(n) additional storage for the builder and resulting string.
There is one useful Unicode detail here. According to Oracle's StringBuilder.reverse() documentation, valid surrogate pairs remain together during reversal. For example, a single supplementary emoji in "A😀B" stays intact, producing "B😀A". That protection is better than a naïve backward char loop, but it is not a promise to preserve every visible character. The Unicode section below explains the difference.
Method 2: reverse with a backward loop
If an exercise asks you to reverse a string in Java without the reverse() method, a loop is an easy way to show the indexing logic:
public static String reverseWithLoop(String text) {
StringBuilder result = new StringBuilder(text.length());
for (int i = text.length() - 1; i >= 0; i--) {
result.append(text.charAt(i));
}
return result.toString();
}
The first index is length minus one because Java strings use zero-based indexing. The loop reads the last char, appends it to the output, and moves left until it reaches index zero. For "desk", it appends k, s, e, and d, returning "ksed".
An empty input has a starting index of -1. The condition is false immediately, so the loop performs no iterations and returns an empty string. There is no need to access index zero as a special case.
Using a builder also avoids repeatedly creating a longer immutable String inside the loop. Code such as result = result + text.charAt(i) is simple to read, but repeated concatenation can require copying an ever-growing result and lead to quadratic total work. A builder is a better habit for this pattern.
The limitation is the unit being reversed. charAt() returns a UTF-16 code unit, not necessarily a whole Unicode code point. This loop is useful for ASCII exercises and deliberately code-unit-based data, but it should not be described as safe for arbitrary emoji or international text.
Method 3: swap a character array with two pointers
A two-pointer solution is another common interview approach. Convert the string to a char array, swap the first and last entries, move both pointers inward, and stop when they meet or cross.
public static String reverseWithArray(String text) {
char[] chars = text.toCharArray();
for (int left = 0, right = chars.length - 1;
left < right;
left++, right--) {
char temporary = chars[left];
chars[left] = chars[right];
chars[right] = temporary;
}
return new String(chars);
}
For "code", the first swap exchanges c and e. The second exchanges o and d, leaving "edoc". If the input length is odd, the middle char does not need to move.
The array swaps themselves use constant extra working space, but the complete String-to-String method is not an O(1)-space operation. toCharArray() creates an array, and new String(chars) creates the returned string. Overall, the method uses O(n) additional storage and O(n) time.
This distinction matters when an interview asks for an “in-place” reversal. You can reverse an existing mutable char array in place; you cannot mutate the contents of a Java String in place.
Like the previous loop, this method swaps UTF-16 code units independently. It can reverse the two halves of a surrogate pair, producing malformed text. Choose it to demonstrate the algorithm or when its input restrictions are appropriate—not because it is automatically a more robust alternative to StringBuilder.reverse().
Method 4: reverse Unicode code points explicitly
If your requirement specifically says to reverse code points while keeping supplementary characters intact, use codePoints() and appendCodePoint():
public static String reverseCodePoints(String text) {
int[] points = text.codePoints().toArray();
StringBuilder result = new StringBuilder(text.length());
for (int i = points.length - 1; i >= 0; i--) {
result.appendCodePoint(points[i]);
}
return result.toString();
}
For well-formed input "A😀B", this returns "B😀A". The emoji is represented by one entry in the int array even though it occupies two UTF-16 char values in the original string. This approach is available in Java 8 and later.
Do not replace codePoints() with chars() and assume the result means the same thing. chars() exposes UTF-16 char values as integers; codePoints() combines valid surrogate pairs into their corresponding code points. The Oracle Character documentation explains why Java uses int values to represent all Unicode code points, while a char represents one UTF-16 code unit.
The method is still O(n) time and O(n) additional storage. Its main advantage is that it states the intended reversal unit explicitly. It is not a guarantee that all displayed text will keep the same visual composition.
Unicode: code points are not always visible characters
A visible symbol can contain more than one code point. An accented letter may be stored as a base letter followed by a combining mark. Some emoji use several code points joined into one displayed symbol, and flags can be sequences rather than single code points.
For example, consider this Java input:
String text = "e\u0301x";
It contains e, a combining acute accent, and x. Reversing the code-point order produces x, the accent, then e: "x\u0301e". The accent no longer follows the original e and may visually attach to a different letter. StringBuilder.reverse() and the explicit code-point method both have this limitation.
If the requirement is to keep user-perceived characters intact, the appropriate unit is usually an extended grapheme cluster. Segment the text into clusters, reverse their order, and keep the internal order of each cluster unchanged. Unicode Standard Annex #29 defines the relevant text-boundary rules.
For production multilingual input, choose a segmentation implementation suitable for your supported JDK, Unicode version, and scripts. A library such as ICU4J may be appropriate. Java's text-boundary APIs can also be useful, but check their behaviour against your actual test cases instead of assuming that every current emoji sequence is supported identically on every runtime.
Reversing a string also does not create optical mirror writing. It changes logical order; it does not reflect each glyph. Bidirectional scripts add another distinction between stored order and displayed order. Define the desired result before choosing an algorithm.
Handle null deliberately
Passing null to the standard StringBuilder constructor throws NullPointerException. That can be a sensible contract when missing input is invalid. If you want a more explicit error message, check the argument first:
public static String reverseRequired(String text) {
if (text == null) {
throw new NullPointerException("text must not be null");
}
return new StringBuilder(text).reverse().toString();
}
If preserving null is the intended behaviour, make that visible in the method:
public static String reverseOrNull(String text) {
return text == null
? null
: new StringBuilder(text).reverse().toString();
}
Avoid automatically converting null to an empty string unless the application explicitly requires it. Missing input and deliberately empty input can mean different things, and merging them can hide validation mistakes.
Test more than one ordinary word
A useful test set checks the contract, the indexing, and the text model—not just whether "Java" becomes "avaJ".
- "Java" should become "avaJ".
- An empty string should remain empty.
- "a" should remain "a".
- "racecar" should remain "racecar".
- "ab cd" should become "dc ba".
- "A😀B" should become "B😀A" with the standard StringBuilder method.
- "e\u0301x" should produce code-point order "x\u0301e"; the combining accent can move visually.
- null should produce NullPointerException with the standard method unless you deliberately add a different policy.
Also test punctuation, leading and trailing spaces, line breaks, and representative text from the languages your application handles. Full-string reversal reverses whitespace positions too: it does not trim the result or preserve the original word order.
If you test the loop and char-array methods, include a supplementary character to reveal their surrogate-pair limitation. A method that passes only ASCII tests has not demonstrated that it preserves arbitrary Unicode text.
Reversing letters is not reversing word order
For "red blue", a full string reversal gives "eulb der". Reversing only the order of the words gives "blue red". These are different operations and should not share a misleading method name.
A simple word-order implementation might split text into words and join them in reverse order, but it must also decide how to treat repeated spaces, tabs, and line breaks. Splitting on whitespace and joining with single spaces deliberately changes formatting. If exact spacing matters, preserve the separators as part of the design.
See our guide to reversing words without scrambling their letters for the distinction. For related programming examples, compare string reversal in Python and JavaScript reversal with Unicode cautions.
Frequently asked questions
Does Java String have a reverse() method?
No. Use a mutable helper such as StringBuilder, then call toString() to obtain a String. Calling text.reverse() on a String does not compile.
Can I reverse a string in Java without a built-in reverse method?
Yes. A backward loop or a two-pointer char-array algorithm demonstrates the logic. Both examples above operate on UTF-16 code units, so document their input restrictions. Use code-point or grapheme-cluster processing when that is the actual requirement.
Does the solution work in Java 8?
Yes. The StringBuilder, loop, and array examples work in Java 8, as does the codePoints() example. No stream-reduction trick or third-party dependency is necessary for ordinary reversal.
Should I use recursion?
Recursion can illustrate an idea, but a simple substring-and-concatenation implementation can add repeated copying and deep call stacks. It is usually a worse default than the short iterative or StringBuilder solutions shown here.
The practical takeaway
Start with StringBuilder.reverse() for a concise solution, keep the original String's immutability in mind, and define your null policy. Use a loop or array when the exercise calls for demonstrating the algorithm. When the input includes multilingual user text, decide whether you need to reverse code units, code points, or complete grapheme clusters, and test that requirement explicitly. That decision matters more than collecting the largest possible list of reversal tricks.
Try the Text Reverser tool
Reverse text, words, or letters instantly — free and entirely in your browser.
Open the tool