关于java的参数传递(值传递、引用传递和传值、传引用)

本文详细解析了Java中参数传递的三种方式:值传递、引用传递(理解为传地址)。值传递是将实参的值复制给形参,不改变实参;引用传递(如传数组时)则是形参和实参指向同一内存地址,修改形参会影响实参。Java中的String对象传递是值传递,而数组传递类似于传地址,修改会改变原数据。

java中参数传递就是用函数调用所给出的实参(实际参数)向函数定义所给出的形参(形式参数)设置初始值的过程。基本的有三种参数分别为:
(1)传值:
(2)传址(即是传指针,java中没有指针,但可以理解成是一个指针)
(3)传引用
值传递和引用传递,即在函数调用时传递的参数,值传递是表示方法接收的是调用者提供的值,引用传递表示方法接收的是调用者提供的变量地址,一个方法可以修改引用传递所对应的变量值,而不能修改值传递所对应的变量值。
值传递:
方法调用时,实际参数把它的值传递给对应的形式参数,函数接收的是原始值的一个copy,此时内存中存在两个相等的基本类型,即实际参数和形式参数,后面方法中的所有操作都只是对形参这个值的修改,不影响实参的值。被调函数的形式参数作为被调函数的局部变量处理,即在堆栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。

引用传递:
方法调用时,实际参数的引用被传递给方法中相对应的形式参数,函数接收的是被引用变量在内存中的地址,在方法执行中形参和实参作用等同,指向同一块内存地址,可以理解成一个指针,方法执行中对引用的操作将会影响到实际对象。被调函数的形式参数虽然也作为局部变量在堆栈中开辟了引用空间,但是这时已经相当于是主调函数放进来的实参变量的别名。被调函数对形参的任何操作都被处理成间接寻址,即通过堆栈中存放的地址访问主调函数中的实参变量。所以被调函数对形参做的任何操作都影响了主调函数中的实参变量。即如果修改传入实参的值,那么内存中该变量的原本的数据也会改变。

当引用作为参数时,传递的是引用类型的地址,引用的地址是无法修改的,但是对引用地址所指向的值是可以进行修改,(String和StringBuffer作为参数是不同的,对于String,String生成实例之后其值无法修改,如果对它进行修改会产生新的对象,所以String的地址传入函数内部时,函数内部对它指向的值进行操作,最终生成了另外一个对象。作为引用传递时,是将新生成的对象替代原对象,可以理解成改变了其指向)

三种传入介绍:

1.传值:是把实参的值赋值给形参,那么对形参的修改,不会影响实参的值。任何的修改都是在实参副本的作用,不会在原传入变量。

2.传地址:是传值的一种特殊方式,只是他传递的是引用地址,不是普通的基本类型,那么传地址以后实参和行参指向同一个对象,当你对传入值操作时,即改变其指向的变量的内容,由于原本其值是指向原来的那个变量,所以也就原来变量的内容。传地址可以理解一种特殊引用传递。

3.传引用:真正的以引用别名的方式传递参数,真正的引用传递。传递形参和实参本质是同一个对象,只是他们名字不同。因为引用就是变量的另一个别名。对形参的修改直接影响实参的值,由于引用是指向某个变量的,对引用的操作也就是对他指向的变量的操作。

因为Java中不存在指针,对于传值还是传地址界线模糊,但是java中变量分为两类,一类是基本变量,一类是引用。下面对于java中传值和传地址举例说明。

例1:

public class J_Test {
	String m_kode = "1";
	String m_king = "2";

	public static void main(String[] args) {
		J_Test  app = new J_Test ();
		app.mb_operat(app.m_kode,app.m_king);
		System.out.print(app.m_kode+app.m_king);
}

	private void mb_operat(String kode, String king) {
		kode = new String("3");
		king  = new String("4");
		
	}
}

代码运行结果如下:
对于值传递的测试
第11行,我们传入实参,但是它的本质其实是进行了值传递。相当于把app.m_kode,app.m_king的值分别传给了静态函数用于接收app.m_kode,app.m_king的局部变量,那么不管传进去是什么值,实参m_kode,m_king的值都不会被改变,**静态方法中后续对于传进去两个值的所有操作以及修改都只是对形参这个值的修改,是对传递值创造的副本的修改,无法对原始数据产生影响。**所以,输出的值还是原始定义的值,值得注意的是,app.m_kode,app.m_king的类型是String,所以最后输出的并不是二者加和,而是字符串的拼接。

例2:

public class J_Test {
	String m_kode = "1";
	String []m_king = {"2"};

	public static void main(String[] args) {
		J_Test  app = new J_Test ();
		app.mb_operat(app.m_kode,app.m_king);
		System.out.print(app.m_kode+app.m_king[0]);
}

	private void mb_operat(String kode, String[] king) {
		kode = new String("3");
		king [0] = new String("4");
		
	}
}

代码运行结果如下:

代码运行结果

对于传入对于形参 String[] king,是传入的数组的地址。当传入数组首地址时,我们可以将数组理解成传入地址,而传入地址,是一种特殊的引用传递。就像C语言中对于串的定义可以使用指针让其指向一个串,也可以建立字符数组,将串的首地址传给字符数组的首地址,在这里,字符数组和指针等价。所以,此时,传入字符数组时,其本质是传入的数组的首地址而非数组的值,与app.m_kode传入的值有根本的区别,也就导致了最终输出结果发生改变。最后做一个串的拼接,输出“14”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值