Parameter passing problem of string type in Java

Source: Internet
Author: User

This article mainly introduces a simple talk about the string type of Java parameter transfer problem related data, the need for friends can refer to the following

Abstract: In the Java language, the "non-object" characteristic of a variable of type String as a method parameter is expounded and analyzed from the angle of realization principle.

First, the first example

Writing code is the most important thing is practice, not through repeated testing and the rhetoric can only be said to be a figment of the imagination. So, in this article, let's start with a simple example to throw the core topic:

?
12345678910111213141516171819 public class StringAsParamOfMethodDemo {     public static void main(String[] args) {        StringAsParamOfMethodDemo StringAsParamOfMethodDemo = new StringAsParamOfMethodDemo();        StringAsParamOfMethodDemo.testA();     }     private void testA() {        String originalStr = "original";        System.out.println("Test A Begin:");        System.out.println("The outer String: " + originalStr);        simpleChangeString(originalStr);        System.out.println("The outer String after inner change: " + originalStr);        System.out.println("Test A End.");        System.out.println();     }     public void simpleChangeString(String original) {        original = original + " is changed!";        System.out.println("The changed inner String: " + original);     } }

The logic of this code is this: first assign a string type of local variable, and then put the variable as a parameter into a method, in this method to change the value of the variable. After compiling the run, we find that the output is this:

?
12345 Test A Begin:The outer String: originalThe changed inner String: original is changed!The outer String after inner change: originalTest A End.

This result indicates that the re-assignment of a variable of type string within the method does not have any effect on the prototype of the variable. Well, the logic and running results of this example are all clear, so let's analyze this little program. Before we do this, we'll look at the so-called "pass-through" and "pass-through" problems in Java.

Ii. "pass-through" and "pass-through" issues in Java

Many novice Java programmers are thinking about this issue because it is the so-called "C-language transfer and pointer problem" in the Java language of similar performance.

The final conclusion is:

In Java, when a primitive type is passed into a method as a parameter, no matter how the parameter is changed within the method, the external variable prototype is always the same, and the code resembles the example above:

?
123 intnumber = 0; changeNumber(number) {number++}; //改变送进的int变量

SYSTEM.OUT.PRINTLN (number); At this point, number is still 0.
This is called "value passing", where a method operates on a parameter variable (that is, a copy of a value of a prototype variable) that changes only one copy of the prototype variable, not the variable itself. So the variant prototype doesn't change with it.

But when a method passes in a non-primitive type (that is, a variable of an object type), the method changes the parameter variable and the variant prototype changes as well, and the code is similar to the example above:

?
123 StringBuffer strBuf = newStringBuffer(“original”); changeStringBuffer(strBuf) {strbuf.apend(“ is changed!”)} //改变送进的StringBuffer变量

System.out.println (STRBUF); At this point the value of Strbuf becomes original is changed!
This attribute is called "reference Pass", also called the address, that is, the method operation parameter variable is a reference to copy the variable, and then by reference to find the variable (here is the object) the real address and manipulate it. When the method ends, the parameter variable inside the method disappears. But to know that this variable is only a reference to the object, it only points to the real address of the object, not the object itself, so it does not have any negative impact. Looking back at the prototype variable, the prototype variable is essentially a reference to that object (the same as the parameter variable), and the change to the object referred to in the parameter variable is simply a change to the object that the prototype variable refers to. So the object represented by the prototype variable is changed, and the change is preserved.

Knowing this classic question, many attentive readers are sure to ask a new question immediately: "But the string type is non-basic in the Java language!" Why hasn't the change in the method been preserved? "Indeed, it is a question, and this new question almost reverses all the conclusions of that classic question." Is that true? OK, now we're going to go on with the analysis.

Third, one of the misinterpretation of string parameter transfer problem --direct assignment and object assignment

How can a variable of type string be passed as a parameter in the same way as a primitive type variable? Some friends have given explanations on this issue, but unfortunately they are not correct.
One explanation is that the assignment of a variable of type string is not a new object, but rather a string assignment, so Java treats the variable of type string as the basic type. That is, it should be string str = new String ("original"), instead of string str = "original";. Is that the problem? Let's take a little makeover of the previous example and see what happens after the run. The modified code is as follows:

?
12345678910111213 private void testB() {    String originalStr = new String("original");    System.out.println("Test B Begin:");    System.out.println("The outer String: " + originalStr);    changeNewString(originalStr);    System.out.println("The outer String after inner change: " + originalStr);    System.out.println("Test B End:");    System.out.println();    } public void changeNewString(String original) {    original = new String(original + " is changed!");    System.out.println("The changed inner String: " + original);    }

Let's take a look at the results of this operation:

?
12345 Test B Begin:The outer String: originalThe changed inner String: original is changed!The outer String after inner change: originalTest B End.

Practice has proved that this statement is wrong.

In fact, the difference between the direct assignment of a string and the assignment of an object with new is only different in the way it is stored.

The following is a brief description:

When a string is directly assigned a value, the value referenced by a variable of type string is stored in the constant pool of the class. Because original itself is a string constant, and on the other hand string is an immutable type, this variable of type string is equivalent to a reference to a constant. In this case, the size of the variable's memory space is determined at compile time.

The new object is stored in the memory space of the string object, and this storage action is performed at run time. Original. In this case, Java does not treat the original string as a constant, because it appears as a parameter to create a string object.

Therefore, there is no direct connection between the assignment method of string and its parameter-value problem. In short, this explanation is not a positive solution.

Four, the distortion of the string parameter transfer problem --"=" Variable value and method variable value

Some friends think that the problem of variable value synchronization is in the way of changing the value.

This argument says: "In Java, change the value of the parameter in two cases, the first, using the assignment number" = "directly assigned to change it, and the second, for some object reference, through a certain way to change its member data, such as through the object itself method. In the first case, the change does not affect data other than the method passed into the parameter variable, or directly to the source data. The second method, in contrast, affects the source data-because the object referenced by the reference does not change, and the change to its member data is essentially the object that is changed. ”

It sounds like something ..., we still use the old method, write the demo, do a little experiment, the code is as follows:

?
12345678910111213     private void testC() {        String originalStr = new String("original");        System.out.println("Test C Begin:");        System.out.println("The outer String: " + originalStr);        changeStrWithMethod(originalStr);        System.out.println("The outer String after inner change: " + originalStr);        System.out.println("Test C End.");        System.out.println(); }     private static void changeStrWithMethod(String original) {        original = original.concat(" is changed!");        System.out.println("The changed inner String: " + original); }

The results are as follows:

?
12345 Test C Begin:The outer String: originalThe changed inner String: original is changed!The outer String after inner change: originalTest C End.

How, this proves that the problem is not here, yet another explanation has died out in the hands of the practical argument.

What is the reason for this situation?

Well, no suspense, here's my explanation.

Five, the crux of the string parameter transfer problem

In fact, the most straightforward way to really understand a class or an API framework is to look at the source code.

Let's look at the small piece of code for the new string object (in the String Class), which is the constructor of the string class:

?
12345678910111213141516171819   public String(String original) {         int size = original.count;         char[] originalValue = original.value;         char[] v;         if (originalValue.length > size) {           // The array representing the String is bigger than the new           // String itself.  Perhaps this constructor is being called           // in order to trim the baggage, so make a copy of the array.           int off = original.offset;               v = Arrays.copyOfRange(originalValue, off, off+size);         } else {           // The array representing the String is the same           // size as the String, so no point in making a copy.           v = originalValue;         }         this.offset = 0;         this.count = size;         this.value = v; }

Perhaps you notice the char[inside], which means that the storage of the string is actually implemented by char[]. What do you think? is actually a layer of window paper. I don't know if you remember those basic types of wrapper classes defined in the Java API. For example, Integer is the int wrapper class, float is the packing class of float and so on. The value operations on these wrapper classes are actually implemented by their corresponding basic type operations. Are you feeling something? Yes, string is equivalent to the wrapper class of char[]. One of the characteristics of a wrapper class is that it reflects the nature of its underlying type when it operates on its value. In the case of parameter passing, the wrapper class is the embodiment. Therefore, the interpretation of the results of the presentation of string in this case is naturally derived. Similarly, Integer, float and so on these wrapper class and string in this case the performance is the same, the specific analysis here is omitted, interested friends can do their own experiments.

This is why when the manipulation of strings is implemented in different ways, it is recommended that you use StringBuffer for real reasons. As for why StringBuffer does not show the phenomenon of string, we look at the implementation of the StringBuffer will understand, here also no longer repeat.

Six, written in the last

The principle of passing a parameter to the string type is also shown. In fact, as long as the analysis of the right way, thinking to come to a correct conclusion.
The basis of the correct analysis method is two:

1, multi-practice: hands do not make lazy, practice will be a genuine knowledge.

2, based on the principle: the most straightforward way to get a clear program logic is to look at the source code, which is beyond doubt.

As long as the analysis based on these two bases, in many cases will achieve a multiplier effect. This is a kind of experience, but also a "shortcut" way to analyze the program.

Ext.: http://www.jb51.net/article/75978.htm

(RPM) Parameter passing problem of string type in Java

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.