Only the value of java object passed, and why?

Before starting depth explanation, it is necessary to correct those errors before you view up. If you have the idea, then you need to take to read this article.

 

A misunderstanding: Condition value is passed and passed by reference, the distinction is content delivery, if it is a value, that value is passed. If a reference is passed by reference.

 

Understanding and error: Java is passed by reference.

 

Misunderstood Three: If the argument passed is a primitive type, it is passed by value, and if the object that is passed by reference.

Real participation parameter

We all know that when the method is defined in Java can be defined parameters. For example, in Java main method:

public static void main(String[] args)

This is inside the args parameter. Parameters are divided into formal and actual parameters in programming languages.

In the form of parameters: the parameter is used in the definition of the function names and function of the body when the object is used to receive incoming calls when the function parameters.

 

Actual parameters: calling the function with a time reference, the data transfer relationship between the calling function and the called function. When you call a function in the calling function, the function name in brackets after the parameter called "actual parameters."

Simple example:

public static void main(String[] args) {
   ParamTest pt = new ParamTest();
   pt.sout("Hollis");//实际参数为 Hollis
}

public void sout(String name) { //形式参数为 name
   System.out.println(name);
}

Actual parameter reference method is invoked when the contents of the real transmission, the formal parameters for receiving the contents of the parameter arguments.

And reference transmission value is passed

I mentioned above, when we call a reference function when will the actual parameters passed to the formal parameters. However, programming languages, in both cases the transfer of this transfer process, that value is passed and passed by reference. We look at the programming language is how to define and deliver value zone and passed by reference.

Value passed (pass by value) refers to the actual argument when calling the function copy passed into the function, so that if the function of the parameter to be modified, will not affect the actual parameters.

 

Reference transmission (pass by reference) refers to the function when calling the address of the actual parameter is directly transmitted to the function, then the modification performed by parameter will affect the actual parameter in the function.

With the above concepts, then you can write code practice, take a look at Java, in the end is passed by value or passed by reference, so the easiest piece of code out:

public static void main(String[] args) {
   ParamTest pt = new ParamTest();

   int i = 10;
   pt.pass(i );
   System.out.println("print in main , i is " + i);
}

public void pass(int j) {
   j = 20;
   System.out.println("print in pass , j is " + j);
}

The above code, we modify the value of the parameter j in the process pass, then the value of the parameter respectively pass printing method and the main method. Output:

print in pass , j is 20
print in main , i is 10

Visible, internal modifications to pass method name value and the actual value of the parameter i does not change. So, according to the above definition, it was the conclusion: Java way to pass is passed by value.

However, it was soon questioned the (ha ha, so do not jumping to conclusions slightly.). Then they will move out of the following code:

public static void main(String[] args) {
   ParamTest pt = new ParamTest();

   User hollis = new User();
   hollis.setName("Hollis");
   hollis.setGender("Male");
   pt.pass(hollis);
   System.out.println("print in main , user is " + hollis);
}

public void pass(User user) {
   user.setName("hollischuang");
   System.out.println("print in pass , user is " + user);
}

The same method is a pass, the same is to modify the value of the parameter in the pass method. Output:

print in pass , user is User{name='hollischuang', gender='Male'}
print in main , user is User{name='hollischuang', gender='Male'}

After a pass execution method, at the arguments now being changed, it passed by reference, as defined above, the actual value of the parameter is changed, it is not passed by reference yet. Thus, according to the above two pieces of code, a new conclusion was obtained: Java method, when an ordinary transfer type is passed by value, when the type of the object is passing reference.

However, this expression is still wrong. I do not believe you can see below this parameter type passed as a parameter object:

public static void main(String[] args) {
   ParamTest pt = new ParamTest();

   String name = "Hollis";
   pt.pass(name);
   System.out.println("print in main , name is " + name);
}

public void pass(String name) {
   name = "hollischuang";
   System.out.println("print in pass , name is " + name);
}

The above code output is

print in pass , name is hollischuang
print in main , name is Hollis

This is what explanation do? Also passing an object, but the original value of the parameter has not been modified, do not pass the object and becomes the value passed?

Value passed in Java

Above, we cite three examples, the result is not the same performance, which is leading to a lot of beginners, and even many senior programmer for the Java transfer type for a reason confusing.

In fact, I want to tell you that the above concept is not wrong, just an example of the code in question. Come, I come to you draw the main points of the concept, and then a few real case in point.

Value transfer (pass by value) means that when you call the function to copy an actual argument passed to the function, so that if modify parameters in functions will not affect the actual parameters.

 tips: modify the parameters, refers to substantial modifications of the parameter itself, in java, the object is referenced parameter, parameter modification itself is stored in a reference value memory address to be modified.

Passed by reference (pass by reference) means that when you call the function directly address the actual arguments passed to the function, then to modify the parameters carried out, it will affect the actual parameters in functions.

Well, I'll give you sum up, what value is passed and references focus on difference of transfer yes.

Several examples of the pass we've seen above, only concerned about whether the actual parameter has changed. User object passed as is, we try to change the value of his name attribute, then check whether there is a change. In fact, the experimental methods are wrong, of course, the conclusion will be a problem.

Why experimental method wrong? Here we give an example of image. Come-depth understanding of what value is passed and passed by reference, then you will know why wrong.

Do you have a key, when your friends want to go to your home, if you put your keys directly to him, which is passed by reference. In this case, the key to this if he did anything like he carved his name on a key, then this key back to you, on your own keys will be more out of his engraved name.

 

Do you have a key, when your friends want to go to your home, you engraved a new key to him, still in his own hands, which is passed by value. In this case, he put what key do this will not affect this key in your hand.

 

However, regardless of the above cases, you give your friend took his keys, into your home, your home television smashed. Then you say you will not be affected? And when we pass the value of the method, the object is to change the user name attribute, not that in "hit television" it. Not that you change the key, but the key to open the house.

Also take an example to the above example, we 真正的改变参数see what happens?

public static void main(String[] args) {
   ParamTest pt = new ParamTest();

   User hollis = new User();
   hollis.setName("Hollis");
   hollis.setGender("Male");
   pt.pass(hollis);
   System.out.println("print in main , user is " + hollis);
}

public void pass(User user) {
   user = new User();
   user.setName("hollischuang");
   user.setGender("Male");
   System.out.println("print in pass , user is " + user);
}

In the above code, we pass method, the user object has changed, the output results are as follows:

print in pass , user is User{name='hollischuang', gender='Male'}
print in main , user is User{name='Hollis', gender='Male'}

Let's draw a picture, look at what is happening throughout the process, then I'll tell you why Java only passed by value.

Explain a little lower this figure, when we create a User object in the main the time, open up a heap memory, which holds data such as name and gender. Hollis then holding the memory address 0x123456(Fig. 1).

When trying to pass method call, and hollis passed as actual parameters to the formal parameters when the user, this will address 0x123456to user, In this case, the user can point to this address (FIG. 2).

然后在pass方法内对参数进行修改的时候,即user = new User();,会重新开辟一块0X456789的内存,赋值给user。后面对user的任何修改都不会改变内存0X123456的内容(图3)。

上面这种传递是什么传递?肯定不是引用传递,如果是引用传递的话,在执行user = new User();的时候,实际参数的引用也应该改为指向0X456789,但是实际上并没有。

通过概念我们也能知道,这里是把实际参数的引用的地址复制了一份,传递给了形式参数。所以,上面的参数其实是值传递,把实参对象引用的地址当做值传递给了形式参数。

我们再来回顾下之前的那个“砸电视”的例子,看那个例子中的传递过程发生了什么。

同样的,在参数传递的过程中,实际参数的地址0X1213456被拷贝给了形参,只是,在这个方法中,并没有对形参本身进行修改,而是修改的形参持有的地址中存储的内容。

所以,值传递和引用传递的区别并不是传递的内容。而是实参到底有没有被复制一份给形参。在判断实参内容有没有受影响的时候,要看传的的是什么,如果你传递的是个地址,那么就看这个地址的变化会不会有影响,而不是看地址指向的对象的变化。就像钥匙和房子的关系。

那么,既然这样,为啥上面同样是传递对象,传递的String对象和User对象的表现结果不一样呢?我们在pass方法中使用name = "hollischuang";试着去更改name的值,阴差阳错的直接改变了name的引用的内存地址。因为这段代码,会new一个String,再把引用交给name,即等价于:

name = new String("hollischuang");

而原来的那个"Hollis"字符串还是由实参持有着的,所以,并没有修改到实际参数的值。

所以说,Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用,对象的内存地址。

总结

无论是值传递还是引用传递,其实都是一种求值策略(Evaluation strategy)。在求值策略中,还有一种叫做按共享传递(call by sharing)。其实Java中的参数传递严格意义上说应该是按共享传递。

按共享传递,是指在调用函数时,传递给函数的是实参的地址的拷贝(如果实参在栈中,则直接拷贝该值)。在函数内部对参数进行操作时,需要先拷贝的地址寻找到具体的值,再进行操作。如果该值在栈中,那么因为是直接拷贝的值,所以函数内部对参数进行操作不会对外部变量产生影响。如果原来拷贝的是原值在堆中的地址,那么需要先根据该地址找到堆中对应的位置,再进行操作。因为传递的是地址的拷贝所以函数内对值的操作对外部变量是可见的。

简单点说,Java中的传递,是值传递,而这个值,实际上是对象的引用。

而按共享传递其实只是按值传递的一个特例罢了。所以我们可以说Java的传递是按共享传递,或者说Java中的传递是值传递。

Guess you like

Origin www.cnblogs.com/parrot/p/11574390.html