C和C++提供了两种参数传递方式,一种是值传递,一种是引用传递,但是在Java中总是使用值传递的方式传递参数,一种是值的拷贝,一种是引用的拷贝,这两者都是值的拷贝,接下来举例子说明。
二话不说直接把测试代码贴上来再分析:
import lombok.Data;
/**
* User: R
* Date: 2018/10/18
* Time: 10:22
* Created with IntelliJ IDEA.
*/
@Data
class Person {
private Long id;
private String name;
public Person(Long id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return "id:" + this.id + ",name:" + this.name;
}
}
public class SomeTest {
public static void main(String[] args) {
Person person = new Person(1001L, "张三");
//1、原始数据
System.out.println("1 -> " + person.toString());
//2、调用changeProperty()之后的数据
changeProperty(person);
System.out.println("2 -> " + person.toString());
//3、调用changeObject()之后的数据
changeObject(person);
System.out.println("3 -> " + person.toString());
}
/**
* 改变对象的属性
*
* @param p
*/
public static void changeProperty(Person p) {
p.setName("李四");
}
/**
* new一个新的对象
*
* @param p
*/
public static void changeObject(Person p) {
p = new Person(1002L, "王五");
}
}
这里有两个方法,changeProperty(Person p)方法是改变传入对象的属性(成员变量),changeObject(Person p)方法是将传入的对象赋予一个新的对象,执行的效果如下:
通过结果我们可以看的出来,调用changeProperty()方法起作用了,但是调用changeObject()方法没有任何变化,下面说一下自己的理解。
1、在调用changeProperty()方法的时候,p得到pserson的引用的拷贝,这时候p和person都引用同一个对象(1001L,"张三"),这时候p改变了其引用对象的值,由于p和person都指向同一个对象,所以person的值也被改变了,方法结束之后p被销毁。
2、在调用changeObject()方法的时候,p得到pserson的引用的拷贝,然后p指向了一个新的对象,由于p只是对person一引用的拷贝,所以p的引用的改变不会影响到person的引用,即p指向了(1002L,"王五")这个对象,但是person的引用没有任何变化,所以调用changeObject()方法之后,person没有任何变化。
现在再举一个通俗一点的例子,比如上文的p和person是两个人,现在有两杯饮料A(张三)和B(王五),值传递和引用传递就好比两个人用一根吸管和两个人分别用两根吸管,在调用changeProperty()方法的时候结果都是一样的,不管是用一根吸管还是两根吸管都是喝的同一杯饮料(张三),但是调用changeObject()方法的时候就会有区别,如果两个人用同一根吸管(引用传递,使用同一个引用),p如果拿上这根共用的吸管去喝B饮料(类似上文的指向王五),那person也只能去喝B饮料(person也指向王五),但是如果是两个人分别用自己的吸管(值传递,引用的拷贝),p拿上自己的吸管去喝B饮料这一个动作对person没有任何的影响。
以上只是个人的理解,如果有理解错误或不恰当的地方请多指教。