top

Search

Java Tutorial

.

UpGrad

Java Tutorial

Why String Is Immutable in Java?

Introduction 

The existence of a string being immutable is only possible for its string pool. Due to this, Java Runtime tends to save tons of space in the system. But the question arises, why is string immutable in Java? 

The String is one of the most used classes in any programming language. It is considered a special class in Java due to its immutability. 

If the string was not immutable in Java, then string interning would be impossible and would have changed the value, which would also reflect in other variables. 

In addition, if the string were not immutable in Java, it would create a security threat to the application. The database username, email, and password would be passed to string, enabling the database connection alongside the socket programming host. The immutability ensures the value remains unchanged and protected from security threats. 

Overview 

This tutorial will cover why string is immutable in Java with real-time examples. You will learn in detail about its benefits and demerits. We’ll also look at examples of how to make a class immutable in Java and walk you through the different immutable objects and their compatibility with Java.  

What Is an Immutable Object?

An immutable object in Java is function-oriented programming whose state cannot be altered post-creation. An object is considered to be immutable when its components cannot be altered even after several upgrades. It is a widely accepted sound strategy that creates robust codes for personal and commercial purposes. 

However, due to their rigid composition, immutable objects in Java are often prone to thread interference or inconsistency. Thus, programmers are reluctant to employ immutable objects because of their cost and rigidity. Since the impact of object creation is overestimated, it causes inefficiency.

What is an Immutable String in Java?

The definition of an Immutable string in Java is not any different from other immutable objects in Java. The term "immutable string" in Java connotes a string object which cannot be altered, but the other object referred to is changeable. 

The string is a crucial component of Java. It is primarily used because of its unchanging value minimizing any security threat. It is safe for multi-reading, and a single string can be used for different threads. 

Example of using a string in Java (and the immutability of strings):

public class ImmutableStringExample {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = str1; // Assign str1 to str2
        System.out.println("Before modifying str1:");
        System.out.println("str1: " + str1); // Output: Hello
        System.out.println("str2: " + str2); // Output: Hello
        // Modifying str1
        str1 = str1 + " World";
        System.out.println("After modifying str1:");
        System.out.println("str1: " + str1); // Output: Hello World
        System.out.println("str2: " + str2); // Output: Hello
    }
}

In this example, we create a string str1 with the "Hello". Then we assign str1 to str2. However, when we modify str1 by concatenating it with " World", a new string object is created with the modified value, while the original str1 remains unchanged. The str2 still refers to the original "Hello" string.

This program demonstrates the immutability of strings in Java. Once a string object is created, its value cannot be modified. Instead, any operation that appears to modify a string creates a new string object with the desired changes.

Why Is String Class Final in Java?

The string class is considered final in Java due to its immutability. It can be finalized in two ways: security and performance. The system can hand out sensitive bits of information without any alterations, and then the string class becomes final in Java. Therefore, with its performance, immutable data is also responsible for ensuring thread safety.

String Pool

The string pool, or the string constant pool, is a special memory area in Java where string literals are stored. String literals are string values that are directly included in the source code.

When string literals are encountered, Java confirms if the same values already exist in the string pools. If the same value exists, the existing string object is reused; otherwise, a new string object is added to the string pool.

Example:

public class StringPoolExample {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = new String("Hello");
        String str4 = "World";
        System.out.println("str1 == str2: " + (str1 == str2)); // Output: true
        System.out.println("str1 == str3: " + (str1 == str3)); // Output: false
        System.out.println("str1.equals(str3): " + str1.equals(str3)); // Output: true
        String str5 = str1 + str4;
        String str6 = "HelloWorld";
        System.out.println("str5 == str6: " + (str5 == str6)); // Output: false
        System.out.println("str5.equals(str6): " + str5.equals(str6)); // Output: true
    }
}

In this example, we create several string variables. str1 and str2 both reference the string literal "Hello". Since this string literal already exists in the string pool, both variables refer to the same string object. Therefore, str1 == str2 evaluates to true.

On the other hand, str3 is created using the new String() constructor, which explicitly creates a new string object, even if the value already exists in the string pool. Therefore, str1 == str3 evaluates to false. However, str1.equals(str3) compares the content of the strings and returns true.

We also concatenate str1 and str4 to create str5 and compare it with str6. Since the concatenation involves runtime operations, a new string object is created for str5. Therefore, str5 == str6 evaluates to false. However, str5.equals(str6) compares the content of the strings and returns true.

It's important to note that while == compares the references of the string objects, the equals() method compares the actual content of the strings.

Thread Safety

Thread safety refers to the property of a code or data structure that ensures it can be accessed and modified correctly by multiple threads simultaneously without causing unexpected behaviors or data corruption.

Example:

In this example, we have a ThreadSafetyExample class with a count variable. The increment() method is synchronized using the synchronized keyword, which ensures that only one thread can execute it at a time. This prevents multiple threads from simultaneously modifying the count variable and causing race conditions.

We create thread1 and thread2, which both call the increment() method in a loop. By starting these threads and waiting for them to complete using the join() method, we ensure they concurrently increment the count variable.

After the threads have finished executing, we print the final value of the count variable. Since the increment() method is synchronized, we can be confident that each thread correctly increments the value, and the final count will be 2000.

By synchronizing the critical section of the code, we achieve thread safety and ensure that the shared data is accessed and modified correctly without conflicts or data corruption.

Benefits of Immutability of String in Java

  • Security 

The immutability of string objects in Java provides a potent security that would not cause any threat to the application. Thus, the value remains unchanged, and the hacker cannot pass through its secure firewall. 

  • Synchronization

String objects that are immutable in Java provide a lot of heap space. This, in turn, can refer to a similar string variable in its pool. If the string is mutable, then the interning string would not be able to help the variable to change its values. This would also reflect gravely in other variables as well. 

  • Hashcode caching

Due to the string's immutability, its hashcode is cached during its making. Hence, there is no need for calculation again. This plays an integral role in a Map where the HashMap key objects are faster than others. Furthermore, because of its immutability, it is widely used around the globe as a HashMap key.

  • Performance

If the user is trying to load java.sql.connection class, and the reference value is changed to myhacked.connection, then it might cause a security threat. However, in the case of Classloader, this will not be an issue and would thereby provide the utmost safety. With immutability, the strings used in Java can provide a correct class for the Classloader alongside a series of optimal performances. 

Demerits of Using String

Even though string pool in Java has various merits, it has certain disadvantages. They are: 

  • Strings consist of a constant value, which, even if altered, cannot reflect changes. Instead, it changes the original string and thus creates a new object. 

  • Many objects are created in bulk. This wastes a lot of memory, and the user must keep updating the value of the string. 

  • Since it uses a lot of memory, the string causes ineffective and inefficient operation. For this reason, StringBuffer and StringBuilder help string with similar yet small operations. However, StringBuffer is considered a better option as it is synchronized while StringBuilder is not.

Important Facts About String and Memory Usage

String objects are considered to be the most used data objects in Java. They have a special arrangement for string objects. They are: 

  • String Constant helps to heap memory space allocated to the string literals using the string objects. 

  • The string is derivative, not primitive, like int, double, etc. 

  • To overcome immutability in string objects, classes like StringBuffer and StringBuilder are introduced in Java. 

  • equals() and hashCode () methods are overridden via string Class which is not overridden through StringBuffer and StringBuilder classes. 

  • StringBuffer objects generally ensure thread safety. 

  • String objects in Java are backed via character arrays. 

Conclusion

String in Java represents a sequence of various characters. It uses java.lang.The string is conventionally used to create a string object. It helps in providing feasible methods for operating on a string. It is essential to secure the code from hackers and promotes string storage. One might often wonder why string is immutable in C# or why is string immutable in Python; the reason remains the same — maintaining security and gaining heap space. 

However, the string class has one disadvantage in Java. It is impossible if the user wonders how to make string mutable in Java. Once the string attains immutability, returning to its previous state is difficult. 

FAQs

1. What is a string class in Java? 

A Java string class represents character strings. Java string literals are implemented as instances of the string class.

2. What is the maximum size of a string in Java? 

The maximum size of a string in Java is around 2,147,483,647. It is subject to change depending upon the number of hex constant digits. 

3. Why is string immutable in most languages? 

Strings are considered concrete objects, also expressed as immutable objects at times. The string helps promote runtime efficiency and improves reliability in object-oriented programming. They are also handy as they promote thread safety. 

Leave a Reply

Your email address will not be published. Required fields are marked *