String Basics & Immutability

Understanding Strings as Reference Types and Why They Cannot Change

CPCS203 - Module 2 | Lesson 1

1 Quick Review: Primitive vs Reference Types

Before we dive into Strings, let's quickly review what we learned in the Arrays module about data types in Java.

Primitive Types

Store the actual value directly in the variable.

int age = 25; // Variable contains: 25 double gpa = 3.75; // Variable contains: 3.75

8 types: byte, short, int, long, float, double, char, boolean

Reference Types

Store the address (reference) to the actual data in memory.

int[] ages = new int[5]; // Variable contains: 0x7A3F // (address pointing to array)

Examples: Arrays, Strings, Objects

Key Point

String is NOT a primitive type! It is a reference type. This means a String variable holds an address pointing to a String object in memory, not the actual characters themselves.

2 How is a String Stored in Memory?

Let's say we want to store "Welcome to Java" in our program. What happens in memory?

String message = "Welcome to Java";
Memory Representation of a String
Stack Memory
message
0x5B2F
String (reference)
Heap Memory (0x5B2F)
String Object
0
W
1
e
2
l
3
c
4
o
5
m
6
e
7
8
t
9
o
10
11
J
12
a
13
v
14
a

Understanding the Structure:

  • The variable message is stored in Stack memory
  • It contains only the address (0x5B2F) pointing to the String object
  • The actual String object is stored in Heap memory
  • The String object contains a sequence of characters (char array internally)
  • Each character has an index starting from 0

3 What is Immutability?

Definition: Immutable

Immutable means "cannot be changed." When we say String is immutable in Java, it means:

Once a String object is created in memory, its content cannot be modified.

This is a very important concept that we will explore in more detail in future lessons about Object-Oriented Programming. For now, let's understand the basics.

Why is String Immutable?

There are several important reasons:

  1. String Interning (Memory Optimization) - We will learn this in the next lesson! It helps save memory by reusing String objects.
  2. Security - Strings are often used for sensitive data (passwords, file paths, network connections). Immutability prevents accidental or malicious modification.
  3. Thread Safety - In multi-threaded programs, immutable objects don't need synchronization because they can't be changed.
  4. Caching - The hash code of a String can be cached because it never changes.

Note for Students: We will discuss thread safety and multi-threading in more detail when we cover StringBuilder and StringBuffer. For now, just understand that immutability is a design decision that provides many benefits.

4 Visualizing Immutability: What Really Happens?

Let's see what happens when we try to "modify" a String. Consider this code:

String s = "Java"; s = s + " Programming"; System.out.println(s); // Output: Java Programming
What You Might Think

Looking at the code, you might think: "The String s was changed from 'Java' to 'Java Programming'."

What Actually Happens:

The original String "Java" was NOT modified! Instead:

  1. A NEW String object "Java Programming" was created
  2. The variable s now points to this new object
  3. The old "Java" object still exists (until garbage collected)
Step-by-Step Visualization
1
String s = "Java";
s
0x100
0x100
"Java"
2
s = s + " Programming";

A NEW object is created!

s
0x200
0x200 (NEW!)
"Java Programming"
0x100
"Java"
Still in memory! Waiting for Garbage Collector
The Key Insight

The original String "Java" at address 0x100 was never changed. It still contains "Java"!

What changed was the reference stored in variable s - it now points to a completely new object at address 0x200.

5 The Danger: String Modification in a Loop

Now let's see why understanding immutability is critical. What happens when we modify a String inside a loop?

String result = ""; for (int i = 0; i < 10; i++) { result = result + i; // String concatenation } System.out.println(result); // Output: 0123456789
What Happens in Memory: 11 Objects Created!

Each iteration creates a NEW String object. The old ones become garbage!

"" (initial)
"0"
"01"
"012"
"0123"
"01234"
"012345"
"0123456"
"01234567"
"012345678"
"0123456789" (final)

10 objects were created and immediately abandoned!

Performance Problem!

Imagine this loop runs 1000 times or 1,000,000 times:

  • Each iteration creates a new String object
  • The old String is discarded (becomes garbage)
  • This wastes memory and CPU time
  • The garbage collector has to clean up all these abandoned objects

Solution Preview:

In Lesson 4, we will learn about StringBuilder and StringBuffer - mutable alternatives that solve this problem efficiently!

6 Proving Immutability with Code

Let's write a simple program to prove that Strings are immutable:

public class ImmutabilityDemo { public static void main(String[] args) { // Create original String String original = "Java"; // Save the original to compare later String saved = original; // Try to "modify" the string original = original.toUpperCase(); // Print both System.out.println("original: " + original); // JAVA System.out.println("saved: " + saved); // Java // Are they the same object? System.out.println("Same object? " + (original == saved)); // false } }

Output:

original: JAVA
saved: Java
Same object? false

Explanation: The saved variable still contains "Java" because the original String object was never changed. The toUpperCase() method created a new String "JAVA" and original now points to that new object.

7 Summary

Key Takeaways
  1. String is a reference type - The variable stores an address, not the actual characters
  2. String is immutable - Once created, the content cannot be changed
  3. "Modification" creates new objects - Operations like concatenation create new String objects
  4. The old objects become garbage - They are eventually cleaned up by the garbage collector
  5. Loop concatenation is inefficient - Use StringBuilder for frequent modifications (we'll learn this later)

What's Next?

In the next lesson, we'll learn about String Interning and the String Pool - how Java uses immutability to save memory by reusing String objects!