Java recognizes the String class (create string, string comparison is equal, string constant pool, understand string immutability)

Understanding the String class

1. Create a string

Common ways to construct String
        //方式一
        String str = "hello";
        System.out.println(str);
        //方式二
        String str2 = new String("hello");
        System.out.println(str2);
        //方式三
        char [] value = {
    
    'h','e','l','l','o'};
        String str3 = new String(value);
        System.out.println(str3);

Insert picture description here
The memory layout of these three methods is as
Insert picture description here
follows:
1. "hello" is a string literal constant, the type is also String.
2. String is also a reference type. String str = "Hello"; The memory layout of such code is as follows in
Insert picture description here
Java Arrays, Strings, and custom classes are all reference types.

Since String is a reference type, for the following code

String str1 = "Hello";
String str2 = str1;

The memory layout is as follows:
Insert picture description here

At this time, after "modifying" str1 to "world", str2 does not change, and it is still hello.

str1 = "world";
System.out.println(str2);
// 执行结果
Hello

In fact, the code like str1 = "world" does not count as "modifying" the string, but makes the reference of str1 point to a new String object.
Insert picture description here

2. String comparison is equal

If there are two int type variables, you can use == to complete.

str1 = "world";
System.out.println(str2);
// 执行结果
Hello
int x = 10 ;
int y = 10 ;
System.out.println(x == y); 
// 执行结果
true

What if you use == on String objects now?

代码1
String str1 = "Hello";
String str2 = "Hello"; 
System.out.println(str1 == str2); 
// 执行结果
true 

Code 1 memory layout:
Insert picture description here
as shown in the figure, str1 and str2 point to the same object. At this time, string constants such as "Hello" are in the string constant pool.

About string constant pool

String literal constants such as "Hello" also require a certain amount of memory space to store. Such constants have a feature that they do not need to be modified (constants). So if there are multiple references in the code, they need to be used For "Hello", just refer to this location of the constant pool directly, and there is no need to store "Hello" twice in memory.

Code 2

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1 == str2);
// 执行结果
false

Code 2: Memory layout:
Insert picture description here
The String object created by String str1 = new String("Hello"); is equivalent to another space on the heap to store
the content of "Hello", that is, there are two copies of "Hello" in the memory ".

String == comparison is not comparing the contents of the string, but comparing whether two references point to the same object.

About the comparison
of objects In object-oriented programming languages, there are three different ways to compare objects, compare identity, compare value, and compare type.
In most programming languages, == is used to compare and compare values.

But the == in Java is used to compare identities.

To compare the contents of strings in Java, you must use the equals method provided by the String class .

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1.equals(str2));
// System.out.println(str2.equals(str1)); // 或者这样写也行
// 执行结果
true

Note for use of equals:
Compare whether the two strings str and "Hello" are equal,

String str = new String("Hello");
// 方式一
System.out.println(str.equals("Hello"));
// 方式二
System.out.println("Hello".equals(str));

I prefer to use "Method Two". Once str is null, the code of Method One will throw an exception, but Method Two will not.

String str = null;
// 方式一
System.out.println(str.equals("Hello"));  // 执行结果 抛出 java.lang.NullPointerException 异 常
// 方式二
System.out.println("Hello".equals(str));  // 执行结果 
false

Note: A literal constant like "Hello" is essentially a String object, and you can use equals and other String object methods.

3. String constant pool

In the above example, there are two instantiation operations of the String class, direct assignment and new a new String.
a) Direct assignment

String str = new String("Hello");
// 方式一
System.out.println(str.equals("Hello"));
// 方式二
System.out.println("Hello".equals(str));
String str = null;
// 方式一
System.out.println(str.equals("Hello"));  // 执行结果 抛出 java.lang.NullPointerException 异 常
// 方式二
System.out.println("Hello".equals(str));  // 执行结果 false
String str1 = "hello" ;
String str2 = "hello" ; 
String str3 = "hello" ; 
System.out.println(str1 == str2); // true
System.out.println(str1 == str3); // true
System.out.println(str2 == str3); // true

Memory layout: Is
Insert picture description here
there no new heap memory space now?
Because the design of the String class uses a shared design pattern
at the bottom of the JVM, an object pool (string constant pool) will actually be automatically maintained at the bottom of the JVM.
If the direct assignment mode is now used to instantiate the String class object, then the instantiated object ( String content) will be automatically saved in this object pool.
If you continue to use the direct assignment mode to declare String objects next time, if there is specified content in the object pool at this time, it will be directly referenced.
If not, create a new string object and save it in the object pool for next use.
b) Using the constructor It
is standard practice to instantiate class objects using the constructor. Analyze the following procedures:

String str = new String(“hello”);

Insert picture description here

  1. If the String construction method is used, two heap memory spaces will be opened up, and one of the heap memory will become garbage space (the string constant "hello" is also an anonymous object, and it will no longer be used after it is used once, and it will become garbage space. Will be automatically recycled by the JVM).
  2. String sharing problem. The same string may be stored multiple times, which is a waste of space.

We can use String's intern method to manually add String objects to the string constant pool.

// 该字符串常量并没有保存在对象池之中
String str1 = new String("hello") ; 
String str2 = "hello" ; 
System.out.println(str1 == str2); 
// 执行结果
false
    
String str1 = new String("hello").intern() ; 
String str2 = "hello" ; 
System.out.println(str1 == str2); 
// 执行结果
true

Insert picture description here
In summary, we generally use direct assignment to create String objects.

4. Understand immutable strings

A string is an immutable object. Its content cannot be changed.

The internal implementation of the String class is also based on char[ ], but the String class does not provide a set method or the like to modify the internal character array.

Feel the code like this and its memory distribution:
Insert picture description here
In fact, multiple temporary objects are re-opened, and the result printed by str after += has changed, but it is not the String object itself that has changed, but that str refers to other objects. .

So if you really need to modify the string, for example, the existing string str = "Hello" and you want to change it to str = "hello", what should you do?

a) Common method: Create a new string with the help of the original string

String str = "Hello";
str = "h" + str.substring(1);
System.out.println(str);
// 执行结果
hello

b) Special method (optional): Using operations such as "reflection" can break the encapsulation and access private members within a class. (I won't elaborate here)

The above are some knowledge points of the String class.

Guess you like

Origin blog.csdn.net/weixin_44436675/article/details/112848872