String, heap area and constant pool

java memory area

Roughly!

Registry
It exists in the cpu and cannot be controlled
stack area
Basic type, reference value is saved
Memory management is done by moving the point back and forth
heap area
New created object
static area
As the word says, static members
constant pool
Data confirmed at compile time and existing in .class + others
Non-RAM area
hdd etc.

String, heap area and constant pool

Main subject: I would like to verify "data that is fixed at compile time and exists in .class".

Verification of familiar contents

Generated in constant pool

String a1 = "aaa";
String a2 = "aaa";
System.out.println(a1 == a2); // true
  1. "aaa" is generated in the contant pool area, and the reference value a1 pointing to "aaa" is generated in the stack area.
  2. Since there is "aaa" in the contant pool area, a reference value a2 pointing to "aaa" is generated in the stack area.
  3. Since both a1 and a2 contain the address of "aaa", it becomes true.

Generated in heap area

String a3 = new String("aaa");
String a4 = new String("aaa");
System.out.println(a3 == a4); // false
  1. "aaa" is generated in the heap area, and the reference value a3 pointing to "aaa" is generated in the stack area.
  2. "aaa" is generated in the heap area, and the reference value a4 pointing to "aaa" is generated in the stack area.
  3. a3 and a4 are false because they contain different "aaa" addresses.

Generated in constant pool, heap area

String a5 = "aaa";
String a6 = new String("aaa");
System.out.println(a5 == a6); // false
  1. "aaa" is generated in the constant pool area, and the reference value a5 pointing to "aaa" is generated in the stack area.
  2. "aaa" is generated in the heap area, and the reference value a6 pointing to "aaa" is generated in the stack area.
  3. a5 and a6 are false because they contain different "aaa" addresses.

Verification of slightly unusual contents

Constant + constant

String a1 = "ab";
String a2 = "a" + "b";
System.out.println(a1 == a2); // true
  1. "ab" is generated in the constant pool area, and the reference value a1 pointing to "ab" is generated in the stack area.
  2. "a" is a constant, "b" is a constant, so a2 = "ab" at compile time. A reference value a2 is generated that points to "ab" that exists in the constant poll.
  3. Since both a1 and a2 contain the address of "ab", it becomes true.
  4. When I took a peek with decompile, it was String a2 =" ab ";.

Constant + new String ("")

String a1 = "ab";
String a2 = "a" + new String("b");
System.out.println(a1 == a2); // false
  1. "ab" is generated in the constant pool area, and the reference value a1 pointing to "ab" is generated in the stack area.
  2. new String ("") is not fixed at compile time. Therefore, "b" is generated in the heap area at the time of execution, and further, the heap area "ab" is generated.
  3. As a result, a1 and a2 are false because they contain different "ab" addresses.

Constant + reference value

String a1 = "ab";
String a2 = "b";
String a3 = "a" + a2;
System.out.println(a1 == a3); // false
  1. "ab" is generated in the constant pool area, and the reference value a1 pointing to "ab" is generated in the stack area.
  2. "b" is generated in the constant pool area, and the reference value a2 pointing to "ab" is generated in the stack area.
  3. Since a2 is a reference value, it is not fixed at compile time. Therefore, "ab" is generated in the heap area at the time of execution, and a3 points to it.
  4. As a result, a1 is a constant pool and a3 is a heap area, so it becomes false.

Constant + final

String a1 = "ab";
final String a2 = "b";
String a3 = "a" + a2;
System.out.println(a1 == a3); // true
  1. With final, a2 is considered a constant and a3 is constant + constant = constant.

Looking at it with decompiler, it was compiled as follows.

String a1 = "ab";
String a2 = "b";
String a3 = "ab";
System.out.println(a1 == a3);

String.intern() A method that can extend the constant pool.

String instance .intern ()

  1. If the same value exists in the constant pool, return its reference value.
  2. If the same value does not exist in the constant pool, generate a value in the constant pool and return its reference value.
String a1 = "ab";
String a2 = new String("ab");
System.out.println(a1 == a2); // false
a2 = a2.intern();
System.out.println(a1 == a2); // true
  1. "ab" is generated in the constant pool area, and the reference value a1 pointing to "ab" is generated in the stack area.
  2. "ab" is generated in the heap area, and the reference value a2 pointing to "ab" is generated in the stack area.
  3. False is omitted.
  4. Since a2.intern () and "ab" exist in the constant pool, return the "ab" address of the constant pool to a2.
  5. Both a1 and a2 point to "ab" in the continuous pool, so it is true.

Bonus: String + causes poor performance

String s = null;
for(int i = 0; i < 100; ++i) {
    s = s + "a";
}

Based on the verification so far Because s in s +" a "; is a variable, a new object is created and destroyed each time it is executed.

Recommended Posts

String, heap area and constant pool
String and stringbuffer and string builder
String literals and instances
[Java] String comparison and && and ||
[Java] Stack area and static area
[Java] About String and StringBuilder
String concatenation and line breaks