Water men, water

Source: Internet
Author: User

Water men, water

Today, a gentleman asked a Java question. What should the following code output:

Class Demo{public static void main(String[] args){String s = "0";change(s);System.out.println(s);}static void change(String s){s = "123";}}

To be honest, when this gentleman asked me a question, I was quite nervous. After all, he used to be an awesome architect in a company.
In addition, people often encounter self-thought-simple problems and often feel that this problem is not simple. For example:
When asked how many times one and one plus one are equal to each other, people often think: this is certainly not as simple as I think. Maybe there is a pitfall waiting for me to jump.
So for the above question, I have gone through the following processes in my mind:

1. the original idea s is an object and is not a basic data type. Therefore, because the parameter is passed as a reference, the value of an attribute in the reference (for example) is changed in the function ), so the value of s in the main function must be changed.
2. The turning point is not that easy. Why should he ask me a question similar to one plus one? It is likely that "0" is printed, but this is not consistent with my inferred results.
3. Is the question "123" printed at the turning point "? What if this question is to test people's psychological quality?

Therefore:

Then I answered "123" unswervingly ". When this gentleman asked me twice, "Are you sure ?" Afterwards, I still think that he is psychologically testing me.
It turns out that I was wrong!
When this gentleman presented the results to me, I thought he was thinking: Dude, what happened to your interview? Isn't it a backdoor to enter the company ?! (Haha ...)
So I was even more nervous at the time. At the same time, my brain was running fast and I was thinking about various causes of this output.

I. Step 1. Now I need to study whether Java function calls are passed values or references?
Previously, I always thought that, except for the basic data types of Java (such as int, long, and so on), other data types (such as String and custom objects) are all referenced and passed. The result is:
By reading various materials, we know that only value passing exists in Java, and a copy will be created during value passing. For example:

class Demo{public static void main(String[] args){User u = new User();u.name = "123";changeName(u);System.out.println(u.name);}void changeName(User u){u = new User();u.name = "0";}}class User{public Strin name;}

The result must be printed 123 instead of 0. The reference is equivalent to the room card, and the object is equivalent to the room. In this example, the room card is passed. In the changeName method, the room card is modified. The room card was originally opened in room 1001, but now the room card has been executed in Room 1002.
So should the room card in the main method point to Room 1002? The answer is no, because when the main method calls the changeName method, It just copies the room card and delivers it to changeName (note that this is not about copying room 1001 to changeName ).
Therefore, the reference value is passed here, and the reference is also a data structure. Like that:


Because Java does not have pointers and it is difficult to perform memory operations, examples similar to the C language seem to better illustrate the problem, as shown below:

#include<stdio.h>#include<malloc.h>#include<string.h>void getSpace(char* str){str = (char*)malloc(sizeof(char)*10);}int main(int argc,char** argv){char* str;getSpace(str);strcpy(str,"nihao");printf("%s\n",str);}

This applet declares a string pointer in the main function, and passes the pointer to the function as a parameter for space allocation.
After the space is allocated, copy a string to the space. And print the content in the space.
The program will terminate abnormally during running. The function parameter here is a pointer, which is similar to a reference in Java.
Although we opened up a space in the getSpace function and pointed the pointer to the new space, the pointer in the main function has not changed, the main function passes only a copy of the pointer value. It is also a copy of the room card, the main function in the room card is still pointing to the original room.


2. The second step is back to the original example:

Class Demo{public static void main(String[] args){String s = "0";change(s);System.out.println(s);}static void change(String s){s = "123";}}

Conclusion obtained through the first step: the main function retains the String s reference and is passed to the change function as the reference copy of s, but they all point to the same area in the heap: 123 ".
So if we change the value of "123" in the heap pointed to by s in the change function, then in principle, the value pointed to by s in the main function will change.

But the problem is that String does not provide a method to change its own value, so s = "123" is equivalent to s = new String ("123 ");!!!!!!!!!!!!!!!!!!!!!! !!, So the "123" area in the heap pointed by s has not changed.
The change also points the room card copy to Room 1002, and the room card in the main function still points to room 1001.
Therefore, for the question asked by the gentleman mentioned earlier, 0 should be output, not 123.

3. The description of step 3 and Step 2 is incorrect! As the saying goes: Let me know the new, when I look at Step 2 again, I think of a problem that I encountered in C language before, as shown below:

#include<stdio.h>int main(int argc,char** argv){char* str="hello";str[1] = 'z';printf("%s\n",str);}

This program is very simple, that is, let a pointer point to a string "hello", and then replace 'E' in "hello" with 'Z '. However, during running, the program exits abnormally because:
For the pointer 'str', we do not allocate space, but direct it to the "Hello" string in the constant pool (Method Area). The content in the constant Pool cannot be changed, A value assignment operation like 4 = 5 is not allowed.
The following example illustrates the problem:

#include<stdio.h>int main(int argc,char** argv){char* str1="hello";char* str2="hello";}

The advantage of C Debugging Over Java is that the memory address where the variable is located can be easily seen. As shown in:


Long-winded, all of the above is to introduce the following theme: Is that true for Java? Is there a difference between String s = "123" and String s = new String ("123? The answer is yes!
We can see the effect through the following two program examples:
Sample Code 1:

String a = "123";String b = "123";a==b; //truea.equals(b);//true

Sample Code 2:

String a = new String("123");String b = new String("123");a==b; //falsea.equals(b);//true

As shown in:




Therefore, it is wrong to say that s in main and s in change pointed to the same content in the heap in step 2. They should point to the same content in the method area.


Note: I sincerely thank this gentleman for teaching me. Since I learned Java, all kinds of frameworks have been around the sky, and various new technologies have been constantly trying, but I have ignored the fundamentals.
Read more, think more, and write more!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.