How to Reverse a String in Java using Recursion

โšก Smart Summary

Reversing a string in Java with recursion works by peeling off the first character, reversing whatever remains, and appending that first character to the end. An empty string stops the calls and unwinds the stack.

  • ๐Ÿ”˜ Base case: The method returns at once when isEmpty() reports that nothing is left to reverse.
  • โ˜‘๏ธ Recursive step: substring(1) removes the first character and charAt(0) puts it back after the reversed remainder.
  • โœ… Immutability: Every call produces a new String object, because a Java String can never be edited in place.
  • ๐Ÿงช Trace: Guru99 becomes 99uruG after seven calls, one for each character plus the empty base case.
  • ๐Ÿ› ๏ธ Faster options: StringBuilder.reverse() and a two-pointer swap over toCharArray() both finish in a single pass.
  • ๐Ÿ“Œ Cost: Recursion with substring() runs in quadratic time and holds one stack frame per character.

Java program that reverses a string using a recursive method

In this example program, we will reverse a string entered by a user.

We will create a function to reverse a string. Later we will call it recursively until all characters are reversed. Recursion suits this problem because a reversed string is simply the reversed tail of the string with the original first character stuck on the end, which is the same problem one character smaller.

Write a Java Program to Reverse String

The class below declares the input in main(), hands it to reverseString(), and prints what comes back. Two println() calls inside the method make each recursive step visible in the console.

package com.guru99;
 
public class ReverseString {
 
	public static void main(String[] args) {
 
 
		String myStr = "Guru99";
 
 
		//create Method and pass and input parameter string 
		String reversed = reverseString(myStr);
		System.out.println("The reversed string is: " + reversed);
		
	}
 
 
	//Method take string parameter and check string is empty or not
	public static String reverseString(String myStr)
	{
		if (myStr.isEmpty()){
		 System.out.println("String in now Empty");	
		 return myStr;
		}
		//Calling Function Recursively
		System.out.println("String to be passed in Recursive Function: "+myStr.substring(1));
		return reverseString(myStr.substring(1)) + myStr.charAt(0);
	}
 
}

Code Output:

Each line of the output is one recursive call. The tail printed on every line is one character shorter than the line above it, and the final line shows the reversed result.

String to be passed in Recursive Function: uru99
String to be passed in Recursive Function: ru99
String to be passed in Recursive Function: u99
String to be passed in Recursive Function: 99
String to be passed in Recursive Function: 9
String to be passed in Recursive Function: 
String in now Empty
The reversed string is: 99uruG

How the Recursive Reversal Works Step by Step

Two lines carry the whole method. The base case, if (myStr.isEmpty()), gives the recursion somewhere to stop. The recursive line, return reverseString(myStr.substring(1)) + myStr.charAt(0), splits the work in two: substring(1) is everything after the first character, and charAt(0) is that first character, appended after the reversed remainder.

Tracing the input Guru99 makes the order clear. Java pushes one frame for each call before any concatenation happens:

CallmyStrPassed to the next callExpression waiting to finish
1Guru99uru99reverseString(“uru99”) + G
2uru99ru99reverseString(“ru99”) + u
3ru99u99reverseString(“u99”) + r
4u9999reverseString(“99”) + u
5999reverseString(“9”) + 9
69(empty)reverseString(“”) + 9
7(empty)base case reachedreturns the empty string

The stack then unwinds from the bottom up, and each frame appends its saved character: the empty string becomes 9, then 99, then 99u, 99ur, 99uru, and finally 99uruG. Because Java strings are immutable, none of these intermediate values overwrites the previous one โ€” every concatenation allocates a new String object.

Two details in the console output are worth naming. The sixth line ends with nothing after the colon, because substring(1) on a one-character string returns the empty string rather than null. The message that follows reads “String in now Empty” in the original program; the wording is a typo for “String is now empty” and has been left untouched so the code and the output above still match line for line.

Other Ways to Reverse a String in Java

Recursion is the clearest way to see the reversal happen, but it is rarely the way production code does it. Three alternatives cover almost every real case.

1. StringBuilder.reverse() is the shortest and the fastest. The class carries a built-in reverse() method, so the whole job fits on one line:

String reversed = new StringBuilder(myStr).reverse().toString();

2. A for loop with charAt() walks the string backwards from the last index to zero. Interviewers often ask for this version because it shows the logic instead of delegating it:

String reversed = "";
for (int i = myStr.length() - 1; i >= 0; i--) {
    reversed = reversed + myStr.charAt(i);
}

3. A two-pointer swap over toCharArray() converts the string to a char array, then trades the outermost characters inwards until the pointers meet in the middle:

char[] chars = myStr.toCharArray();
int left = 0;
int right = chars.length - 1;
while (left < right) {
    char temp = chars[left];
    chars[left] = chars[right];
    chars[right] = temp;
    left++;
    right--;
}
String reversed = new String(chars);

The same array technique reverses a numeric sequence or any other ordered collection, which is why it turns up in Java array exercises as often as in string ones.

Time and Space Complexity of Each Approach

The four versions do not cost the same. Both quadratic entries below share one cause: they create a brand-new String on every step, and copying n characters n times is n squared work.

ApproachTimeExtra spaceWhy
Recursion with substring()O(n²)O(n²)substring() copies the remaining characters on every call, and one stack frame is held per character
for loop with charAt() and +O(n²)O(n²)Each concatenation allocates a new String and copies everything gathered so far
StringBuilder.reverse()O(n)O(n)One mutable buffer, one pass, and surrogate pairs are kept intact
Two pointers over toCharArray()O(n)O(n)One array copy, then n/2 swaps with no further allocation

Pick the recursive version to learn or to demonstrate how the call stack behaves, the char-array version when an interviewer asks for the logic by hand, and StringBuilder.reverse() in anything that ships. The same trade-off between a teaching solution and a production one shows up across the classic exercises, from bubble sort and the Fibonacci series to prime number checks; each one is worth practising in Java both ways.

FAQs

String objects are immutable, so the characters inside one can never change after creation. Every reversal therefore builds a new object. Use StringBuilder or a char array when the characters must be modified without allocating a new String each step.

The first call to isEmpty() throws a NullPointerException, because the method is invoked on nothing. Guard the entry point with a null check that returns null or throws IllegalArgumentException before any recursion begins.

Not reliably. charAt() works on 16-bit code units, so a character stored as a surrogate pair is split and the reversed text shows replacement squares. StringBuilder.reverse() keeps surrogate pairs together, which makes it the safer choice for Unicode text.

StringBuilder, in almost every case. Both expose the same reverse() method, but StringBuffer synchronises every call, which costs speed. Choose StringBuffer only when one buffer is genuinely shared between threads.

Split the sentence on whitespace with split(” “), then walk the resulting array from the last index to the first, appending each word to a StringBuilder. The characters inside each word stay in their original order.

One stack frame is used per character, so a few thousand characters is typical before a StackOverflowError appears. The exact limit depends on the JVM thread stack size. Any iterative version avoids the ceiling entirely.

An AI assistant can read a stack trace, point at a missing or unreachable base case, and explain the order in which frames unwind. It also drafts edge-case tests for empty, single-character, and null input. Verify the reasoning against a real run.

Yes. Copilot usually completes a whole reverse method from the signature alone, often offering the StringBuilder form first. Check the base case and the complexity, because the shortest suggestion is not always the version an exercise asks for.

Summarize this post with: