✈️ Go Up

XIYO's Hole

Go to Nav

Memory Storage of Literals

Literals are fixed values directly assigned to variables in programming languages. This article explores how Java literals are stored and managed in memory.

What are Literals?

Literals are data that appear directly as values in code. For example, the number 10, string "Hello", and boolean value true are all literals. Simply put, literals are the data itself used in code.

Common types of literals include:

  • Integer literals: 10, -42, 0, 9999L
  • Floating-point literals: 3.14f, 0.5
  • Character literals: 'A', 'B'
  • String literals: "Hello", "World"
  • Boolean literals: true, false

How Literals are Stored

The way literals are stored in memory depends on whether the variable is a primitive type, wrapper class, or string.

Primitive Variables

When a literal is assigned to a primitive variable, the value is stored directly in the variable's memory space. For example, when the integer literal 10 is assigned to a primitive variable, the value 10 is stored directly in the variable's memory space. This is fast and efficient.

Code Example:

public class Main {
    public static void main() {
        int intVal = 3;
    }
}

Memory Diagram:

Primitive variables store bit data directly on the call stack.

Wrapper Classes and Strings

Wrapper classes (Integer, Double, etc.), which are reference types for primitives, and the String class are stored in a special space called the Constant Pool. If the same value already exists in the constant pool, the existing address is returned to save memory.

Code Example:

public class Main {
    public static void main(String[] args) {
        Integer intVal = 3;
        String str = "hello";
    }
}

Memory Diagram:

Wrapper classes and strings reference values stored in the constant pool.

Comparison of Wrapper Classes and Strings

Since wrapper classes and string literals reference addresses in the constant pool, they always reference the same instance even when the same value is created multiple times. In contrast, when objects are created using the new keyword, new objects are created in heap memory instead of the constant pool.

Code Example:

public class ConstantPoolTest {  
    public static void main(String[] args) {  
        A a = new A();  
        B b = new B();  
  
        System.out.println(a.instanceStr == b.instanceStr);  // true  
        System.out.println(a.instanceStr == b.newStr);       // false  
        System.out.println(a.instanceStr == b.internStr);    // true  
        System.out.println(a.instanceStr.equals(b.newStr));  // true  

        System.out.println(a.instanceInt == b.instanceInt);  // true  
        System.out.println(a.instanceInt == b.newInt);       // false  
        System.out.println(a.instanceInt == b.internInt);    // true  
        System.out.println(a.instanceInt.equals(b.newInt));  // true  
    }  
}  
  
class A {  
    String instanceStr = "instanceStr";  
    Integer instanceInt = 1;  
}  
  
class B {  
    String instanceStr = "instanceStr";  
    String newStr = new String("instanceStr");  
    String internStr = newStr.intern();  

    Integer instanceInt = 1;  
    Integer newInt = new Integer(1);  
    Integer internInt = newInt.intValue();  
}

The intern() method finds the same value in the string constant pool and returns its address.

Objects created with literals share the same constant pool address, resulting in 'true' comparisons, while objects created with the new keyword are created separately in heap memory, resulting in 'false' comparisons.