Strings in Java are immutable, once declared they cannot be changed.
Tags: java, beginners, tutorial
Published: 2023-01-21 18:51:06

# String Pool

Strings in Java are immutable. It means that its value once declared cannot be changed anymore. The String variables just stores references to the String value on Heap memory, and it can be changed, like we used to do during the execution of our program.

When a literal String is declared, it is saved on a specific local of the Heap memory: the `String Pool`.

To clarify it better, let's declare a new String variable on our Java class.

```java
public class Application {
    public static void main(String[] args) {
        String myFirstString = "Hello";
    }
}
```

When we declare a String variable and initialize it with the literal way, that is what happen at the memory allocated to our application.

![Line1](https://user-images.githubusercontent.com/71560285/211213239-0c6494ba-df89-442d-8460-0f3685979a52.png)

Declaring another String variable using the same literal attribution, another local on String Pool won't be created, since the JVM knows that there already exists a String value declared as `Hello`.

**Code**
```java
public class Application {
    public static void main(String[] args) {
        String myFirstString = "Hello";
        String mySecondString = "Hello";
    }
}
```

If we look at memory:

![Line2](https://user-images.githubusercontent.com/71560285/211213463-f14388ea-88ed-46d7-acff-c81c07ee075b.png)

At the beginning, the String Pool is empty. After declaring the `myFirstString`, JVM looks inside it and search for the value "Hello". If it still doesn't exist, JVM stores that value and return the address. If already exists, returns the address of the value.

To make sure that `myFirstString` and `mySecondString` are appointing to the same local of memory, we can compare them with the `==` operator, which returns true if they have the same address.

**Code**
```java
public class Application {
    public static void main(String[] args) {
        String myFirstString = "Hello";
        String mySecondString = "Hello";

        System.out.println("Has same address: " + (myFirstString == mySecondString));
    }
}
```

**Result**
```
Has same address: true
```

If we change both values, the `Hello` will not be removed from memory, it just will not have a pointer with its address, and another allocation on String Pool will be created, having the new declared value.

**Code**
```java
public class Application {
    public static void main(String[] args) {
        String myFirstString = "Hello";
        String mySecondString = "Hello";

        myFirstString = "World";
        mySecondString = "World";

        System.out.println("Has same address: " + (myFirstString == mySecondString));
        System.out.println("Has same address as \"Hello\" value: " + (myFirstString == "Hello"));
    }
}
```

**Result**
```
Has same address: true
Has same address as "Hello" value: false
```

**Memory Representation**

![Line3](https://user-images.githubusercontent.com/71560285/211213258-32b92f42-baf2-4ce0-8be3-9bfd9f13df38.png)

There we can see the immutable propriety, since the value stored did not change after an alteration of variables's value attribution, and other local on String Pool was occupied with the new value.

It is important to say that if we declare a String variable with the `new` keyword, that value will not be created at String Pool, instead of it, will be saved at Heap Space every time a String is declared with the `new` keyword.

**Code**
```java
public class Application {
    public static void main(String[] args) {
        String myLiteralString = "Hello";
        String myNewString = new String("Hello");

        System.out.println("Has same address: " + (myLiteralString == myNewString));
    }
}
```

**Result**
```
Has same address: false
```

**Memory Representation**

![Line4](https://user-images.githubusercontent.com/71560285/211213264-93b03eb4-6bb3-46f7-8293-db27d6e7c482.png)

To allocate that value on String Pool, we can manually use the `String.intern()` method.

**Code**
```java
public class Application {
    public static void main(String[] args) {
        String myLiteralString = "Hello";
        String myNewString = new String("Hello");

        System.out.println("Has same address: " + (myLiteralString == myNewString));

        myNewString = myNewString.intern();
        System.out.println("Has same address after intern: " + (myLiteralString == myNewString));
    }
}
```

**Result**
```
Has same address: false
Has same address after intern: true
```

**Memory Representation**

![Line5](https://user-images.githubusercontent.com/71560285/211213273-fe89dc92-e5e9-41cc-8c16-6a74ddf2ae3f.png)

#### Advantages
- The use of String Pool improves the performance of our application, since it works as a cache, allowing the JVM to also spend less memory.
- Allows reusability of String values.
- Allows more security for Strings that cannot be change during the execution of our project (like passwords).

#### Disadvantages
- Every time a String is changed, another value will be allocated in memory, and the old value will be still existing, using unnecessary space. When working with some String variable that changes a lot, that can be a memory problem.

It is possible to use Strings on a mutable way through Java `StringBuilders`. Using that resource, the String value will not be stored on String Pool and the allocated value will be changed at the same address, not being reallocated.

Of course, we can have some cases that Immutable Strings cannot solve our problem, and be a problem of performance. **You need to understand your case for the best application**.

That topic about String Pool is based on [Scaler](https://www.scaler.com/topics/java/string-pool-in-java/), [Baeldung](https://www.baeldung.com/java-string-pool), [Coding with John](https://www.youtube.com/watch?v=Bj9Mx_Lx3q4) and [Vogella](https://www.vogella.com/tutorials/JavaIntroduction/article.html#javastringpool).

That's all ;D
Please any feedbacks, improvements or revisions are welcome.