Reprint please indicate the source: juejin.cn/post/684490…

This article is from Rong Hua Xie Hou’s blog

0. Write first

I did a common Java interview question in the past two days, but I made a mistake without any doubt. After running the correct answer, I found that I could not fully explain why with my knowledge reserve. I felt ashamed, so I wrote this article to summarize and reflect on it.

1. The subject

Let’s look at the title:

public class Test { public static void main(String[] args) { String str = "hello"; change(str); System.out.println(str); A a = new A("hello"); change(a); System.out.println(a.str); A a1 = new A("hello"); change1(a1); System.out.println(a1.str); } private static void change(String str) { str = "changed"; } private static void change(A a) { a = new A("changed"); } private static void change1(A a1) { a1.str = "changed"; } } class A { public String str; public A(String str) { this.str = str; }}Copy the code

The running results are as follows:

hello
hello
changed
Copy the code

The first value is hello, and the value is reassigned to STR. The second value is the same as the last value.

After experiencing the above doubts, after a meal of Baidu, err, Google, found that the following concepts are not very thorough understanding:

  • What are stack memory and heap memory, and what are the differences?

  • How does initializing a primitive type data or an object work in memory?

  • Where is String data stored in memory?

  • String STR = “a”; And String STR = new String(“a”); What is the difference in memory allocation?

With these questions, look down together.

Stack memory, heap memory

Stack memory

Some basic types of variables defined in functions (byte, short, int, long, float, double, Boolean, char) and reference variables of objects (Object obj = new Object(); Obj for reference variables) are allocated in the stack memory of the function.

When a variable is defined in a block of code, Java allocates memory for that variable on the stack. When the scope of the variable is exceeded, Java automatically releases the allocated memory for the variable, which can be immediately used for other purposes.

The advantage of stack memory is that access is faster than the heap, second only to registers, and stack memory data can be shared. However, the disadvantage is that the size and lifetime of the data in the stack must be determined, which lacks flexibility.

Heap memory

Objects and arrays created by new (array new or not) are stored in heap memory, and memory allocated in the heap is managed by the JVM garbage collection mechanism.

An object or array stored in the heap memory can correspond to a reference variable in the stack memory. The value of the reference variable is the first address of the object or array in the heap memory. The program can operate on the array or object through the reference variable in the stack memory.

Object obj = new Object(); Obj is a reference variable that can be used to manipulate Object.

3. Allocate memory for basic types of data and objects

Basic type data

int a = 1;
int b = 1;
int c = 2;
Copy the code

Step analysis:

  • 1. Create a reference to a in the stack memory, and then check if 1 exists in the stack memory. If not, store 1 in the stack memory and point a to 1.

  • 2. Create a reference to b in stack memory, and then check whether 1 exists in stack memory. If found, point b to 1.

  • 3. Create a reference to c in stack memory, and then check if 2 exists in stack memory. If not, store 2 in stack memory and point c to 2.

As you can see from the above steps, the data in stack memory can be shared. Although the data is shared, the modification of variable B does not affect variable A.

object

Object obj = new Object();
Copy the code

Step analysis:

  • 1. Create a reference to the variable obj in stack memory.

  • 2. Create an Object in the heap memory. The heap memory automatically calculates the first address of the Object, for example, 0x0001.

  • 3. The variable obj in stack memory points to the first address 0x0001 of the Object in heap memory.

4. Type String

The String type is special in that it is not a primitive data type, but it can be assigned with = like a primitive data type. It can also be created with new. Let’s see how the two methods differ in memory.

String str = “a”;

Step analysis:

  • 1. Create a reference to the variable STR in stack memory.

  • 2. Create a string a in the constant pool.

  • 3. The variable STR in stack memory refers to the string A in the constant pool.

String str = new String(“a”);

Step analysis:

  • 1. Create a reference to the variable STR in stack memory.

  • 2. Create a String in the heap. The heap automatically calculates the first address of the String, assuming 0x0001.

  • 3. The variable STR in stack memory points to the first address of String 0x0001 in heap memory.

  • 4. The String object first looks for the String a in the constant pool. If it does, it points to String A.

5

After learning the above knowledge, let’s go back to analyze the interview question:

public class Test { public static void main(String[] args) { // A String str = "hello"; change(str); System.out.println(str); // B A a = new A("hello"); change(a); System.out.println(a.str); // C A a1 = new A("hello"); change1(a1); System.out.println(a1.str); } private static void change(String str) { str = "changed"; } private static void change(A a) { a = new A("changed"); } private static void change1(A a1) { a1.str = "changed"; } } class A { public String str; public A(String str) { this.str = str; }}Copy the code

Use A, B, and C to mark the three sections of logic.

  • A:

Step analysis:

  • 1. Create a reference to a variable named STR (argument) in stack memory.

  • 2. Create a string hello in the constant pool.

  • 3. The variable STR (argument) in stack memory refers to the string Hello in the constant pool.

  • 4. Create a reference to a variable named STR (parameter) in stack memory.

  • 5. Create a string changed from the constant pool.

  • 6. The variable STR (parameter) in stack memory points to the string changed in the constant pool.

The value of the argument STR is printed, printing hello

  • B:

  • 1. Create a reference to a variable named a (argument) in stack memory.

  • 2. Create a String object in heap memory with address 0x0001 and reference variable A (argument) to this address.

  • 3. The String object looks for the String Hello in the constant pool. If it does not find the String hello, it creates the String hello in the constant pool and points to it.

  • 4. Create a reference to a variable named a (parameter) in stack memory, pointing to address 0x0001.

  • 5. Create a String object in the heap with the address 0x0011 and reference variable A (parameter) to this address instead of 0x0001.

  • 6. The String object first looks for the String changed in the constant pool. If it does not find the String, create the String changed in the constant pool and point to it.

The value of argument A is printed, and hello is printed

  • C:

  • 1. Create a reference to a variable named a1 (argument) in stack memory.

  • 2. Create a String object in heap memory with address 0x0001 and reference variable A1 (argument) to this address.

  • 3. The String object looks for the String Hello in the constant pool. If it does not find the String hello, it creates the String hello in the constant pool and points to it.

  • 4. Create a reference in stack memory to a variable named a1 (parameter) pointing to address 0x0001.

  • The String object first looks for the String changed in the constant pool. If it does not find the String changed, create the String changed in the constant pool and point to it instead of pointing to the String Hello.

At this point, print the value of argument A, printing changed

6. Write at the end

Here, about the summary of this Java interview question is completed, associated with many things, if you encounter problems or have the wrong place, you can give me a message, thank you!