这段代码是看了hollis的文章之后写的,看完能对值传递和引用传递的理解更清晰一点
package com.lix.nacoscommon;
import lombok.Data;
import org.junit.Test;
/**
* 解释为何java中只有值传递
* 主要是概念问题:
* 值传递:值传递(pass by value)是指在调用函数时将实际参数“复制”一份传递到函数中,这样在函数中如果对“参数”进行修改,将不会影响到实际参数。
* 引用传递:引用传递(pass by reference)是指在调用函数时将实际参数的地址“直接”传递到函数中,那么在函数中对“参数”所进行的修改,将影响到实际参数。
* @author lix
* date 2019-08-05 16:49
*/
public class ValueTransmitTest {
@Test
public void intTransmit(){
int a = 1;
transmit(a);
System.out.println("main:"+a);
}
/**
* 将a copy了一份,所以main中a的不变
* @param a
*/
private void transmit(int a) {
a = 2;
System.out.println("assistant:"+a);
}
@Test
public void beanTransmit(){
User user = new User();
user.setAge(18);
user.setName("Me");
bean(user);
System.out.println("main:"+user);
}
/**
* 将user的值copy了一份,即user的地址copy了一份,
* 但是user的引用和copy的引用还是相同的,此时修改了引用对应的堆中user对象的值
* 结果导致在main中输出的user的参数的值改变了,而实际上user没变(他的引用没变)
* @param user
*/
private void bean(User user) {
user.setName("You");
System.out.println("assistant:"+user);
}
@Test
public void beanTransmitV2(){
User user = new User();
user.setName("Me");
beanV2(user);
System.out.println("main:"+user);
}
/**
* 将user的值copy了一份,即将user的地址copy了一份
* 然后让copy出来的user指向了new User,即他改变的是新的user,未将堆中的老user的参数进行修改
* 所以主方法中的user不变
* 如果是引用传递的话,主方法中的user就应该被改变成新的user了
* 主要是这块比较绕,可以多想想,需要结合java内存模型
*/
private void beanV2(User user) {
user = new User();
user.setName("You");
System.out.println("assistant:"+user);
}
@Data
private class User{
private String name;
private Integer age;
}
@Test
public void stringTransmit(){
String str = "Me";
string(str);
System.out.println("main:"+str);
}
/**
* 将str的地址 copy过来,然后str的指向进行了改变
* “You”相当于new String("You")
* 如果使用StringBuilder的话,改了就会改了
* @param str
*/
private void string(String str) {
str = "You";
System.out.println("assistant:"+str);
}
@Test
public void stringBuilderTransmit(){
StringBuilder str = new StringBuilder("Me");
stringBuilder(str);
System.out.println("main:"+str);
}
/**
* 将str的地址copy过来,然后进行了改变
* @param str
*/
private void stringBuilder(StringBuilder str) {
str.reverse();
System.out.println("assistant:"+str);
}
}