#
String, StringBuffer and StringBuilder
This tutorial explains the difference between String, StringBuffer and StringBuilder in Java.
Please take a look at the following examples and read carefully the comments. The code is self-explanatory.
This example is created from a simple Spring Boot application created with Spring Initializr. I am using Maven, Java 17, Spring Boot 3.1.0.
Starting from the base application downloaded from Spring Initializr, I updated the main class as below:
DemoApplication.java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import java.util.concurrent.ExecutionException;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ApplicationContext appContext = SpringApplication.run(DemoApplication.class, args);
String str1 = "ABC";
String str2 = "ABC";
String str3 = str1;
System.out.println("--- String : -------------");
// You will see that each String has the same address as reference.
System.out.println("identityHashCode (str1)="+System.identityHashCode(str1));
System.out.println("identityHashCode (str2)="+System.identityHashCode(str2));
System.out.println("identityHashCode (str3)="+System.identityHashCode(str3));
str3 = "JJJ";
System.out.println("str1="+str1);
// The address (reference) will change as the new String is created (having another value)
// The conclusion: the Strings are immutable
System.out.println("identityHashCode (str3)="+System.identityHashCode(str3));
String str5 = new String("ABC");
// This String is not created in the String Pool, so it receive another address internally
System.out.println(System.identityHashCode(str5));
System.out.println("----------------------------");
System.out.println("--- StringBuffer : --------");
StringBuffer sb1 = new StringBuffer("ABC");
StringBuffer sb2 = sb1;
// Both variable point to the same address
System.out.println("identityHashCode (sb1)="+System.identityHashCode(sb1));
System.out.println("identityHashCode (sb2)="+System.identityHashCode(sb2));
sb2.append(" Hello ");
// When a variable change the addresses are not changed
System.out.println(">> identityHashCode (sb1)="+System.identityHashCode(sb1));
System.out.println(">> identityHashCode (sb2)="+System.identityHashCode(sb2));
// When you change a variable you change the other one as well
// The conclusion: the StringBuffers are mutable
System.out.println("sb1="+sb1);
System.out.println("sb2="+sb2);
// When creating a new variable using the "new" operator, the address is always different
StringBuffer sb3 = new StringBuffer("ABC");
System.out.println("identityHashCode (sb3)="+System.identityHashCode(sb3));
System.out.println("----------------------------");
System.out.println("--- StringBuilder : --------");
StringBuilder sBuilder1 = new StringBuilder("ABC");
StringBuilder sBuilder2 = sBuilder1;
sBuilder1.append(" Hello ");
System.out.println("sBuilder2="+sBuilder2);
StringBuilder sBuilder3 = new StringBuilder("ABC");
// The behaviour for StringBuilder is the same as for StringBuffer,
// however, the StringBuffer operations are thread-safe and synchronized.
// In the same time with synchronization we loose speed.
System.out.println("identityHashCode (sBuilder1)="+System.identityHashCode(sBuilder1));
System.out.println("identityHashCode (sBuilder2)="+System.identityHashCode(sBuilder2));
System.out.println("identityHashCode (sBuilder3)="+System.identityHashCode(sBuilder3));
}
}
When I run this code I get the following log:
--- String : -------------
identityHashCode (str1)=848409667
identityHashCode (str2)=848409667
identityHashCode (str3)=848409667
str1=ABC
identityHashCode (str3)=1729904998
1406221524
----------------------------
--- StringBuffer : --------
identityHashCode (sb1)=2005293363
identityHashCode (sb2)=2005293363
>> identityHashCode (sb1)=2005293363
>> identityHashCode (sb2)=2005293363
sb1=ABC Hello
sb2=ABC Hello
identityHashCode (sb3)=1293465402
----------------------------
--- StringBuilder : --------
sBuilder2=ABC Hello
identityHashCode (sBuilder1)=393549265
identityHashCode (sBuilder2)=393549265
identityHashCode (sBuilder3)=1392482765
Remarks:
- Strings are immutable while StringBuffer and StringBuilder are mutable.
- StringBuffer operations are thread-safe (synchronized) and StringBuilder operations are not thread-safe (are not synchronized).
- Because of the synchronization, StringBuffer are slower than StringBuilder.