public class TestTransForValue {
public void changeValue1(int age) {
age=30;
}
public void changeValue2(Person person) {
person.setPersonName("xxx");
}
public void changeValue3(String str) {
str="xxx";
}
public static void main(String[] args) {
TestTransForValue test = new TestTransForValue();
int age = 20;
test.changeValue1(age);
System.out.println("age----"+age);//age----20
Person person = new Person("abc");
test.changeValue2(person);
System.out.println("personName---"+person.getPersonName());//personName---xxx
String str = "abc";
test.changeValue3(str);
System.out.println("String---"+str);//String---abc
}
}
基本类型,按值传递。实际上是将参数的值作为一个副本传进函数中,,函数中改变的是副本的值,而不是原值,所以在main函数中的原值不变。
引用类型:传的是对象的地址,即引用
图中的age打印出来是20,因为age是基本类型 传递的是值的副本 在方法内改变的是副本的值,原值还是20没有改变 因此在main线程中打印出的age还是20.
那么personName打印出来为什么是xxx呢?
=后面new出来的对象是在堆中,必然有一个地址要指向这个对象的在堆中的位置,即main方法中的 person会有一个引用指向堆中的对象,在调changeValue2方法后也传入了person ,这个person引用也指向了堆中的对象,在进入changeValue2修改了该对象的内容后 main里面的person打印出来的内容就会改变 因为两个 person指向了同一个对象。
str打印出来是abc 是因为String会放在字符串常量池中 两个str开始会指向同一个地址,在执行到changeValue3方法时,将"xxx"的值赋给了str 首先他会在常量池中找"xxx",找到了就指向他重新 复用 没找到就会重新创建一个指向他,因此打印出来的main方法里的str就是原来的abc
总结
一、“传值”传递的是一个值,而“传引用”传递的是指向一个另一块内存空间的地址;
二、“传值”实际是将一个值的拷贝传递至方法内部,这个值的原始数据是不会改变的,无论你内部进行的是何种操作,都不会改变这个源数据的值;而“传引用”传递进去的则是指向一个对象的地址,那么在方法内部进行实际操作的时候,就很可能会改变该对象的属性值(当然具体是否改变,还需要结合具体的业务)。