Java中,方法中所有参数都是“值传递”,也就是“传递的是值的副本”。 也就是说,我们得到的是“原参数的复印件,而不是原件”。因此,复印件改变不会影响原件。
1、基本数据类型参数的传值
传递的是值的副本。
副本改变不会影响原件。
2、引用类型参数的传值
传递的是值的副本。
但是引用类型指的是“对象的地址”。
因此,副本和原参数都指向了同一个“地址”,改变“副本指向地址对象的值,也意味着原参数指向对象的值也发生了改变”。
示例:多个变量指向同一个对象
/**
* @ClassName: User4
* @Description: TODO(测试java的参数传值机制:多个变量指向同一个对象)
*/
public class User4 {
int id; //id
String name; //账户名
String pwd; //密码
public User4(int id, String name) {
this.id = id;
this.name = name;
}
public void testParameterTransfer01(User4 u) {
u.name = "小八";
}
public void testParameterTransfer02(User4 u) {
u = new User4(200, "小六");
Sysotem.out.println(u.name);
}
/**
* @Title: main
* @Description: TODO(测试java的参数传值机制:多个变量指向同一个对象)
*/
public static void main(String[] args) {
User4 u1 = new User4(100, "Charlie");
//测试参数传递01方法
u1.testParameterTransfer01(u1);
System.out.println(u1.name);
//测试参数传递01方法
u1.testParameterTransfer02(u1);
System.out.println(u1.name);
}
}
运行结果:
分析:
1、主函数新建个对象u1,名字叫Charlie;
(堆中产生id=100,name=“Charlie”的新建对象,假设此对象地址为123,即u1=123)
2、有个 testParameterTransfer01()方法(测试参数传递方法01),将u1传递给了01方法的形参u;
(调用01方法时,相当于把u1=123这个地址传递给了01方法的形参变量u,所以u=123)
(u1指向了name=“Charlie”的对象,u此时也指向了该对象)
(当u.name="小八"时,就把对象的“Charlie”改为了“小八”)
通过u.name=“小八”,这个u变量将对象u1的名字改为小八;
(所以再执行u1.name时,打印了“小八”)
3、执行完 testParameterTransfer01()这个方法,控制台打印小八,对象u1的名字已改为小八;
说明对象u1的内容变了;
注:java里的值传递,是拷贝值得内容;
但是传对象时,多个变量会指向同一个对象,那么一个变量改变了对象的值,其他地方的变量也会改变;
深入:
1、建立新的方法 testParameterTransfer02()
建立新的对象 u = new User4(200, “小六”);
把u传进来,赋了新的对象(200,“小六”)
(产生u1对象(100,“Charlie”),u1的地址为123,指向了这个对象)
(把u1地址传给01方法的u,因此u=123,所以u.name=“小八”,所以01方法下打印u.name=“小八”,方法执行完后,u变量就没有了)
2、执行完02方法后,在打印u1.name;
结果没变化
(再执行02方法时,又产生一个u,依然是把u1的地址传过来。因此u=123,所以此时u也指向这个对象)
(执行02方法时,新建了id=200,name=“小六”的对象,假设地址为124,因此u的地址也变为124,若在02方法内打印u.name,因为此时u指向地址为124的对象,因此打印出“小六”)
(新的指向新的,以前的指向以前的,因此在外面打印u1.name还是打印出“小八”)
因为u1的地址还是123,所以u1.name=“小八”
注:传地址的拷贝,有可能改变以前对象的值,一定要注意这一点