Java中的方法参数传递机制

目录

1. 方法调用

2. 按值传递

3. 引用传递

4. 可变参数

5. 引用类型数组


1. 方法调用

       一个方法只有被其它方法调用才能运行。Java应用程序的运行总是从main()方法开始,main()方法又称为主方法,主方法可以调用任何其它方法,但不允许被其它方法所调用。除了main()方法外,其它任何方法的关系都是平等的,它们之间可以相互调用。方法调用的一般形式如下:

       对象名或类名.方法名([实参列表]);

       对于有参数方法的调用,向其传递的参数称为实际参数,简称实参。实参不需要加数据类型,其可以是常数、变量或者表达式,各个实参之间用逗号隔开,实参的个数、类型、顺序要和方法定义的参数一一对应。方法定义时的参数称为形式参数,简称形参,形参前必须有数据类型,而没有具体数值,其需要方法调用时将实参传递给它之后才具有数值。

2. 按值传递

       当参数的数据类型是基本数据类型时,实参和形参之间是按值传递。按值传递是指调用方法将实参的“值”传递给形参,也就是说被调用方法中形参的值是调用方法指定的值的拷贝。按值传递时,实参和形参在内存中占据不同的空间,因此当实参的值传递给形参后,两者之间将互不干扰,形参值的改变不会影响原来实参的值。

【例1】按值传递示例。

public class ValueTransferDemo {
	public static void change(int x) {
		x=20;
		System.out.println("被调用方法:x="+x);
	}
	public static void main(String[] args) {
		int x=10;
		change(x);
		System.out.println("调用方法:x="+x);
	}
}

        程序运行的结果为:

        被调用方法:x=20

        调用方法:x=10

       通过程序的运行结果可以看出,main()方法中的变量x,在调用方法change()之后其值并没有发生变化,仍然是10。在执行change()方法时,尽管形参x的值被设置为20,但是它并不影响main方法中变量x的值,这是因为main()方法在调用change()方法时向其传递的只有实参x的拷贝。

       图1描述了参数按值传递的过程。Main()方法中定义的变量x在内存中的存储示意图如图1(a)所示。当main()方法调用change()方法时,系统进入change()方法,main()方法中的变量x作为实参传给change()方法,此时传入的只是x的拷贝,而不是x本身,如图1(b)所示。程序在change()方法中改变了形参x的值,该值只是change()方法中的局部变量,其变化并不影响main()方法中的变量x的值,如图1(c)所示。

图1. 按值传递过程

3. 引用传递

       当参数的数据类型是引用数据类型时,实参向形参传递的是“地址”,而不是具体的值,被调用方法通过传递的地址获取实参所指向的内存空间,因此,当其修改了形参的值时,实参的值也会发生改变,这就是引用传递与按值传递的区别。

【例2】引用传递示例

public class ReferenceTransferDemo {
	public static void change(Data data) {
		data.x=20;
		System.out.println("被调用方法:data.x="+data.x);
	}
	public static void main(String[] args) {
		Data data=new Data();
		data.x=10;
		change(data);
		System.out.println("调用方法:data.x="+data.x);
	}
}
class Data{
	int x;
}

       程序运行的结果为:

       被调用方法:data.x=20

       调用方法:data.x=20

       通过程序执行结果可以看出,main()方法中的变量data对象,其成员变量x在调用change()方法后发生了变化,由10变为20。这是因为传递给change()方法的形参是一个对象,对象是引用数据类型,所以,实参会将地址传递给形参,它们都指向了内存中的同一地址空间,形参值发生变化,实参值也会随之变化。

       图2描述了参数按引用传递的过程。在main()方法中创建了一个Data类的对象data,并将该对象的成员变量x的值赋予20,此时的内存模型如图2(a)所示。当main()方法调用change()方法时,系统进入change()方法,main()方法中的对象data作为实参传给change()方法,此时传入的是对象data在内存中的地址,这样,实参和形参都指向data对象,此时的内存模型如图2(b)所示。程序在change()方法中改变了对象data的成员变量x的值,将其设置为10,由于形参和实参都指向同一对象,因此,main()方法中data对象的成员变量x的值也变为10,如图2(c)所示。

图2. 引用传递过程

4. 可变参数

       可变参数是指在方法声明时不给出参数列表中从某项直至最后一项参数的名称和个数,但是这些参数的数据类型必须相同,其语法格式如下:

        [访问符] [修饰符列表] <返回类型> 方法名([参数列表],数据类型…变量){

                方法体

        }

       定义可变参数时应注意如下要点:

        (1)可变参数只能处于参数列表的最后。

        (2)一个方法最多只能包含一个可变参数。

        (3)调用一个包含可变参数的方法时,既可以传入多个参数,也可以传入一个数。

【例3】可变参数示例。

public class VariableParameterDemo {
	//带可变参数a的方法
	public static int sum(int x,int ... a) {
		int sum=x;
		for(int i=0;i<a.length;i++) {
			sum+=a[i];//可变参数被当作数组来处理
		}
		return sum;
	}
	public static void main(String[] args) {
		int x=10;
		int a[]= {2,4,6,8};
		//调用带可变参数的方法,传入多个参数
		System.out.println("x+2+4="+sum(10,2,4));
		System.out.println("x+2+4+6="+sum(10,2,4,6));
		//调用带可变参数的方法,传入一个数组
		System.out.println("x+a[0]+a[1]+a[2]+a[3]="+sum(10,a));
	}
}

        程序运行结果为:

        x+2+4=16

        x+2+4+6=22

        x+a[0]+a[1]+a[2]+a[3]=30

5. 引用类型数组

       如果一个数组的数据类型为类,那么该数组称为引用类型数组。对引用类型的数组,使用new运算符只是为数组本身分配空间,并没有对数组的元素进行初始化。因此,对于引用类型数组,需要经过两步进行空间分配:创建数组本身和创建数组元素。下面以一维数组为例来说明引用数组的空间分配过程。

       ①创建数组本身:

        类名 数组名[];

        数组名=new类名[数组长度];

        或者

        类名 数组名[]=new类名[数组长度];

        ②创建数组元素:

        数组名[0]=new 类名([参数列表]);

        数组名[1]=new 类名([参数列表]);

        …

        数组名[数组长度-1]=new 类名([参数列表]);

        创建引用类型数组示例:

        //创建一个长度为5的Rectangle型数组

         Rectangle rectangle[];

         rectangle = new Rectangle[5];

         //创建3个Rectangle型的数组元素

         rectangle[0]=new Rectangle(1.0,1.0);

         rectangle[1]=new Rectangle(2.0,1.5);

         rectangle[2]=new Rectangle(3.5,3.0);

       图3描述了数组rectangle的内存空间分配过程。

        语句:Rectangle rectangle[];

        执行完毕,系统为数组分配一个引用空间,它在内存中还没存放任何值,其内存模型如图3(a)所示。

       语句:rectangle = new Rectangle[10];

       执行完毕后,系统在内存中为数组分配了相应的地址空间,这个地址空间的首地址被放到引用rectangle内,此时的内存模型如图3(b)所示,此时,还不能使用数组元素。

        语句:

        rectangle[0]=new Rectangle(1.0,1.0);

         rectangle[1]=new Rectangle(2.0,1.5);

         rectangle[2]=new Rectangle(3.5,3.0);

       执行完毕后,系统在内存中创建了三个Rectangle对象,并将它们的地址分别放到引用rectangle[0]rectangle[1]rectangle[2]中,此时的内存模型如图3(c)所示,此时,可以使用这三个数组元素,但是,还不能使用后面两个数组元素,因为它们还有被分配内存空间。

图3. 引用类型数组内存分配过程示意图

数组属于引用型变量,因此两个相同类型的数组如果具有相同的引用,它们就有完全相同的元素。

【例4】将一个数组的引用赋给另一个数组。

public class FinalizeDemo {
	public static void main(String[] args) {
		int a[]= {1,2,3},b[]={4,5};
		a=b;//将数组b的引用赋给数组a
		System.out.println("a.length="+a.length);
		for(int i=0;i<a.length;i++) {
			System.out.print(a[i]+" ");
		}
	}
}

程序运行结果为:

a.length=2

4 5

语句:a=b;

执行后,数组a也指向了数组b的引用,因此,它的长度变为2,而不是3,此时,数组元素的值为4和5。

  • 29
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值