Java方法参数传递

按值调用(call by value)表示方法接收的是调用者提供的值。

按引用调用(call by reference)表示方法接收的是调用者提供的变量地址。

一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。

Java总是采用按值调用,方法得到的是所有参数值的一个拷贝,方法不能修改传递给它的任何参数变量的内容。
eg.

	public static void change(int x){
		x++;
		System.out.println("x = "+x);
	}
	public static void main(String[] args) {
		int a = 1;
		change(a);
		System.out.println("a = "+a);
	}

上面代码执行后,输出的结果如下

看一下具体的执行过程:

1.x被初始化为a的一个拷贝,也就是1;

2.x执行x++后等于2,此时a依旧是1;

3.方法结束后,参数变量x不再使用。

方法参数共有两种类型:基本数据类型和对象引用。已经看到,一个方法不能修改基本数据类型的参数,而对象引用作为参数就不同了,看下面的例子

先建一个学生类,简单的有姓名和年龄两个属性。

public class Student {
	private String name;
	private int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
}

利用下面方法实现年龄增长

	public static void change(Student a){
		a.setAge(a.getAge()+1);
		System.out.println(a.getName()+"'s age is "+a.getAge());
	}
	public static void main(String[] args) {
		Student stu = new Student("Stan",9);
		System.out.println(stu.getName()+"'s age is "+stu.getAge());
		change(stu);
		System.out.println(stu.getName()+"'s age is "+stu.getAge());
	}
上面代码执行后,输出的结果如下

已经看到,实现一个改变对象参数状态的方法并不是一件难事,理由很简单,方法得到的是对象引用的拷贝,对象引用及其拷贝同时引用一个对象。

看一下具体的执行过程:

1.a被初始化为stu值的拷贝,这里是对象的引用;

2.change方法应用于这个对象的引用,stu和a同时引用的那个Student对象的年龄+1;

3.方法结束后,参数变量a不再使用,而变量对象stu继续引用那个年龄+1的学生对象。

回到最初的起点,很多程序设计语言提供了两种参数传递的方式,就是文章开头提到的按值调用和按引用调用,看到这里可能大家认为Java对对象采用的是按引用调用,实际上这种理解是错误的,文章开头已经有了说明Java总是采用按值调用,方法得到的是所有参数值的一个拷贝,方法不能修改传递给它的任何参数变量的内容。

下面举一个反例来阐述这个问题。

同样是Student类,现在写一个交换学生的方法。

	public static void change(Student a,Student b){
		Student temp = a;
		a = b;
		b = temp;
		System.out.println("a's name is "+a.getName());
		System.out.println("b's name is "+b.getName());
	}
	public static void main(String[] args) {
		Student stu1 = new Student("Stan",9);
		Student stu2 = new Student("Kyle",9);
		System.out.println(stu1.getName()+"'s age is "+stu1.getAge());
		System.out.println(stu2.getName()+"'s age is "+stu2.getAge());
		change(stu1,stu2);
		System.out.println(stu1.getName()+"'s age is "+stu1.getAge());
		System.out.println(stu2.getName()+"'s age is "+stu2.getAge());
	}
如果Java程序设计语言对对象调用采用的是按引用调用,那么这个方法就应该能实现交换数据的效果,stu1变成Kyle而stu1变成Stan。

但是让我们看看执行结果

方法并没有改变存储在变量stu1和stu2中的对象的引用。change方法的参数a和b被初始化为两个对象引用的拷贝,这个方法交换的是这两个拷贝,即a和b的引用发生了改变,相互引用了对方的对象,但stu1和stu2没有改变,没有对stu1和stu2产生影响。

最终,在方法结束时参数变量a和b被废弃了,原来的变量stu1和stu2依然引用这个方法调用之前所引用的对象。

这个过程说明,Java程序设计语言对对象采用的不是按引用调用,实际上,对象引用进行的是值传递。即把引用的值传递进去赋值给参数,产生一个新的引用。

下面是总结:

1.一个方法不能修改一个基本数据类型的参数;

2.一个方法可以改变一个对象参数的状态;

3.一个方法不能让对象参数引用一个新的对象从而传递出来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值