Recognize the String class (issues related to string and memory layout (1))

1. Create a string

Common ways to construct String

// 方式一
String str = "Hello Bit";
// 方式二
String str2 = new String("Hello Bit");
// 方式三
char[] array = {
    
    'a', 'b', 'c'};
String str3 = new String(array);

In the official document ( https://docs.oracle.com/javase/8/doc/api/index.html ) we can see that String also supports many other construction methods, we can check it when we use it. .

Precautions:

  • String literal constants like "hello" are also String.
  • String is a reference type . String str ="Hello";

The code memory layout is as follows:

Memories "quote"

  • References are similar to pointers in C language, except that a small memory space is opened on the stack to store an address. However, references and pointers are not the same, pointers can perform various numerical operations (pointer + 1), etc., but References cannot be made, this is a kind of "not so flexible" pointer.
  • In addition, you can also think of a reference as a label, which is "pasted" to an object. An object can be affixed with one label or multiple. If an object does not have a label on it, then the object will be treated as garbage by the JVM The object is recycled.
  • Arrays, Strings, and custom classes in Java are all reference types.

Since String is a reference type, for the following code

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

The memory layout is shown in the figure:
Insert picture description hereWill str1 and str2 be modified accordingly?

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

We found that after "modifying" str1, str2 did not change, or is it hello?
In fact, the code like str1 = "world" is not a "modified" string, but makes the reference of str1 point to a new String Object.

Memory layout diagram:
Insert picture description here

2. String comparison is equal

If there are two int type variables, you can use == to complete the judgment of their equality.

int x = 10 ;
int y = 10 ;
System.out.println(x == y); 
// 执行结果
true

If you say that == is used on Stringg objects now?

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

It seems that there is no problem, try another code, and find that the situation is not very good

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

Analyze the difference between the two ways of creating String.

Code memory layout 1:
Insert picture description here We find, str1 and str2 point to the same object is time as "Hello" is a string constant such. A string constant pool of.

Regarding the 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 too many in the code If you need to use "Hello" in any reference, you can directly refer to this location in the constant pool, and there is no need to store "Hello" in memory twice.

Code 2 memory layout:
Insert picture description here

By String str1 = new String("Hello");String objects created in such a manner equivalent to the heap and then opened up additional space to store the contents of "Hello", that is, there is the memory of two "Hello".

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, comparing identities, comparing values, and comparing types. In most programming languages ​​== is used to compare and compare values. But in Java The == is used to compare identities.
How to understand the comparison value and compare identities? You
can imagine a scene where you can pick up express delivery and there are parcel lockers. There are many grids on it. There are things in each grid.

If you want 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

Notes on using equals
Now we need to compare whether the two strings str and "Hello" are equal, how do we write it?

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

It is more recommended 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.
1. Direct assignment

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

Insert picture description hereWhy hasn't a new heap memory space been opened up now?

The design of the String class uses a shared design pattern

In fact, an object pool (string constant pool) is automatically maintained at the bottom of the JVM

  • If the direct assignment mode is now used to instantiate an object of the String class, 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 the String class object next time, if there is specified content in the object pool at this time, it will be directly referenced
  • If not, open up a new string object and save it in the object pool for next use

Understanding "pool" (pool)

  • "Pool" is a common and important way to improve efficiency in programming. We will encounter various "memory pools", "thread pools", "database connection pools" in our future learning...
  • However, the concept of Chi is not unique to computers, but also comes from life. For example: in
    real life there is a goddess, called "green tea", while talking about objects with Gao Fushuai, she may also engage with other dicks Ambiguous. At this time, this diaosi is called a "spare tire". So why have a spare tire? Because once you break up with Gao Fushuai, you can find a spare tire immediately, which is more efficient .
  • If this goddess is ambiguous with many dicks at the same time, then these spare tires are called spare tire pools.

2. Using the construction method It
is standard practice to instantiate class objects using the construction method. Analyze the following procedures:

String str = new String("hello");

Insert picture description hereThis approach has two disadvantages:

  1. If the String construction method is used, two heap memory spaces will be opened up, and one of the heap memory spaces will become garbage space (the string constant "hello" is also an anonymous object, after it is used once, it will no longer be used, 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 the intern method of String 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 hereInterview question: Please explain the difference between the instantiation of the two types of objects in the String class

  1. Direct assignment: Only a piece of heap memory space will be opened, and the string object can be automatically saved in the object pool for next use.
  2. Construction method: Two heap memory spaces will be opened up and will not be automatically saved in the object pool. You can use the intern() method to manually enter the pool.

Therefore, we generally use direct assignment to create String objects.

Guess you like

Origin blog.csdn.net/qq_47364122/article/details/112968111