Immutable Strings In Java

In Java String objects are immutable. As you probably already know immutability means unchanging once the object is created.

In this short tutorial we will examine why Strings are immutable in Java. Immutability can be a desirable property of an object.

Immutability has a number of benefits which include:

  • Simplified Concurrent Code.
  • Functional Programming Friendly.
  • Increased understanding.
  • Possibility of reduced software bugs.
  • Can reduce memory consumption, and improve performance if techniques are applied, such as: caching and reuse.

You can read more about immutable objects in Java here.

Strings Are Immutable

We have said that Strings are immutable, but what exactly does this mean. Let’s look at an example, by considering the String below:

1
String immutableString = "Hello Strings";

If we try to perform a mutable operation on the String immutableString that would result in a modification to it’s value, we will receive a reference to the modified String.

1
String newImmutableString = immutableString + " are immutable";

Above we perform string concatenation, by appending the string “are immutable”. Instead of changing the value of the immutableString variable the operation returns a reference to the string:

1
Hello Strings are immutable

Moreover, if we look at some of the operations of the String class:

1
2
3
4
5
6
7
8
9
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    public String replace(CharSequence target, CharSequence replacement)

    public String substring(int beginIndex)

    public String concat(String str)

}

We can confirm that mutating operations return a reference to a new String.

Why Are String Immutable

Strings are immutable to improve the performance of Java applications and reduce their memory footprint. For example if a Java application contains the same String value contained in five different variables such as:

1
2
3
4
5
String str1 = "Strings Are Immutable";
String str2 = "Strings Are Immutable";
String str3 = "Strings Are Immutable";
String str4 = "Strings Are Immutable";
String str5 = "Strings Are Immutable";

If we consider that variables store their values in memory, we may come to the conclusion that the five Strings above are stored in separate memory locations.

Moreover, if we are familiar with software design patterns, and we are wearing our software engineering hat with pride, we may contemplate the flyweight design pattern. For those not familiar with the flyweight design pattern it has the purpose of reducing memory usage through reuse.

In this case we may come to the conclusion that storing the five strings in separate memory locations is a waste of valuable system resources. However, the engineers that created the Java language thought the same.

String Pool

To reduce the memory footprint of Strings, the JVM comes with a String pool. The String pool is a special memory location where Strings are stored.

Java String Pool

In this case when we use a String literal in Java, the String pool is consulted, and a reference to a String in the String pool is returned, if its found. Therefore, the variables str1 to str5 all point to the same string in memory.

Now consider what would happen if we modify the str1 variable.

1
str1 = "Modified String";

Above we set the str1 variable to a new String value. Moreover, if Strings were not immutable this operation would change the value of the variables: str2, str3, str4, and str5. This would give any Java developer a major headache.

Therefore, the Java engineers decided to make Strings immutable, to increase performance and simplify programming tasks.

Hashcode Caching

The hashcode of a String is frequently used in Java. When we add a String as a key to a HashMap, put it into HashSet etc, the String’s hashcode must be computed. Therefore, to reduce calculating a hashcode every-time it is required / accessed. The Java String class caches its hashcode value.

The immutable property of a string guarantees, the hashcode will always be the same. Moreover, because Strings are immutable, it helps to ensure that values are not lost in a hashing data structures such as a HashMap.

Security

Strings sometimes represent important pieces of information, such as usernames, passwords, file paths, database connections etc. If a String was mutable it may cause a security vulnerability within our application.

For example if a String’s value was validated, and then after this validation the String could be modified, it would allow an attacker to circumvent the security checks.

1
2
3
4
5
6
7
8
public void sensistiveTask() {

    if(!securityChecksPass(str)) {
        throw new SecurityException("Action not allowed");
    }

    performSensitiveOperation();
}

Concurrent Programming

Since String objects are immutable they can be safely used across threads. Any change to a String will be local to the thread in which it was mutated.

Conclusion

In this short tutorial we examined why Strings are immutable in Java.