This article is participating in “Java Theme Month – Java Debug Notes Event”, see < Event link > for more details.

preface

  • We all know that Java strings are immutable. Characters created by double quotes are stored in the constant pool.

Problem description

  • But why did it go wrong? The problem persists after submitting to the constant pool via INTERN. Let’s take a closer look

[TOC]

Why strings are immutable in Java. Today we’ll take a look at many aspects of why Java made strings immutable.

Constant pool

  • There are two basic ways to create strings in Java.

String str1 = "zxhtom";
String str2 = new String("zxhtom");

Copy the code
  • In the above two ways we create two String variables. But the first type of zxhTom object created by double quotes is what we call a constant. In the JVM it is stored in a pool called the Constant pool. And the second type str2 is what we call the ordinary variable. New opens up a chunk of memory in the JVM at a time.
  • The constant pool is used for reuse. Java points to the same block of address when the same content is created constantly-again. Understood by the following code:

String z1 = "zxhtom";
String z2 = "zxhtom";

Copy the code

  • We can see from the above figure that z1 and z2 actually refer to the same memory address. So z1==z2 is true.

  • This raises the question of why strings are designed to be immutable. In the above column, z1 is changed to ZXH. If String was mutable, z2 would somehow be changed to ZXH.

convenient

  • In Java, two objects are equal by address. But the address is abstracted as a hash function. Hash is often used in Java usage. Make String immutable so that hash can be used forever. The convenience of not having to recalculate

security

  • Again, z2 will be modified without knowing it. This is common in multithreading. When we use it, the data will be changed by other circumstances. In this way, our data will lose accuracy.

Extended problem

  • In the previous section we mentioned the constant pool of strings. Think about constant pools [string.intern ()]

  • The function of this method is to expand the constant pool. Z2.intern () determines whether an object with the same value exists in the constant pool and returns a reference to the object if so. If not, the value is registered in memory. Note that you are not registering the Z2 object. I’m going to register the value of Z2.


String z1=new String("zxhtom");
String z2=z1.intern();
System.out.println( z1==z1.intern() );
System.out.println( z1.hashCode()+""+z2.hashCode() );
System.out.println( z2==z1 );
System.out.println( z2==z1.intern() );

Copy the code
  • Output structure

false
-688175064 -688175064
false
true

Copy the code
  • Z1.intern () creates the zxhTom value in the constant pool. Z2 refers to the reference in the constant pool. If z1==z2 is false, it is not the address of z1 registered in the constant pool, but a copy of an object equivalent to z1.
  • To determine how to create a string:
    • The == constant created by double quotes
    • Created by constant concatenation == constant
    • Create by concatenating constant with constant = constant
    • Create == very much by new

String in Java

  • Method arguments are passed by value in Java. But why does String give us the feeling of being passed by reference?

public static void main(String[] args) {
	String x = new String("ab");
	change(x);
	System.out.println(x);
}
 
public static void change(String x) {
	x = "cd";
}

Copy the code
  • String is not a basic object so String is passed by reference. But the reference passing knowledge here is passing the address of the String reference. When executing x= CD, the original ab object is still in the JVM. The reference address of external X has not changed. Become aware of the direction of x in the change method. So the external print is still ab