Java中的参数传递方式

博主最先接触的是C和C++,后面自学了Java用到了现在.说来惭愧,没有特地去深究一些基础问题,也是迷迷糊糊的按着C++那一套来,最近开始看<<Thinking in Java>>, 羞于很多基础内容都没有弄明白, 故有此文.


让我们先记住结论: 

1. Java中只有值传递 !只是值的形式不同, 基本数据类型传的值是内容(名副其实的传值), 对象传的值是对象的地址(传值传的值是一个地址).

2. 操纵方法体中的参数, 操纵的是另一个有自己内存空间的变量, 而不是我们传入的变量, 但是这两个变量可以指向同一个对象实体.

3.String虽然不是基本数据类型, 但其在函数参数传递过程中的表现与基本数据类型一致.



造成基本类型变量与对象变量在参数传递过程中, 表现的差异的原因在于在Java中两者容纳的值不同:

对基本类型(int, float, boolean 等)而言, 变量是非句柄变量, 即变量的值容纳的是变量的内容(名副其实的值);

对对象变量而言, 变量是句柄变量, 即变量的值容纳的是操纵对象的句柄(指向对象实体的地址, 所以虽然是值传递, 却表现出了传址的特性);


下面让我们来看具体的例子:

基本类型的参数传递:(String的表现与基本类型一致)

import java.util.*;
public class Test{
        //基本类型的参数传递: 基本类型变量中容纳的就是变量的具体内容,名副其实的传值
	public static void main(String[] args){
	    int ori = 123;
	    System.out.println("ori before execute doubleNum is: " + ori);
	    doubleNum(ori);
            System.out.println("ori after execute doubleNum is: " + ori);
	}
	
	public static void doubleNum(int para){
	    para *= 2;
	}
}

输出: ori的值没有被改变



在参数传递的过程中, 将ori变量所在内存中存放的值(这里由于是基本类型, 所以存放的值就是变量的具体内容, 也就是 123), 传递给了函数doubleNum 的参数 para 的内存空间,  para 对应的内存空间存放的值也变为123, 接下来的doubleNum的操作均是对 参数 para 自己的内存空间的值( para 的具体内容), ori 的值不会受到函数 doubleNum 的影响. 



对象类型的参数传递:

import java.util.*;

class ObjectValues{
     public int objValue;

     public ObjectValues(int a_){
	objValue = a_;
     }
}

public class ValuePass{		
	//对象变量的传值, 传递的值是一个对象的句柄(地址, 不过仍然是传值, 只是值的内容不同), 所以在执行函数之后ob变量的objValue被改变了
	public static void myFunMyObject(ObjectValues o){
	   o.objValue = 123456;
	}
	
	public static void main(String[] args){		
		ObjectValues ob = new ObjectValues(233);
		System.out.println("执行函数前, 对象ob的 objValue 值为: " + ob.objValue);
		myFunMyObject(ob);
		System.out.println("执行函数后, 对象ob的 objValue 值为: " + ob.objValue);
	}
}

输出: 对象ob的objValue被函数改变了


执行 ObjectValues ob = new ObjectValues(233); 语句的时候, 在堆空间内创建了ob对象的实例, 栈空间创建了指向对象实例的句柄. 在参数传递的时候,  句柄ob存放的内容是指向对象实例的地址, 该地址被传递到了参数 o 的空间(依然是值传递, 但是值的内容是一个指向对象实体的地址), 接下来的操作同样只针对参数o的内存空间, 但是由于o 的内存中保存的是指向ob实体的地址(两个内存空间指向了同一个对象实体), 所以我们最终改变了对象ob的objValue.



赋值也是这么一个道理. 

另外, 需要特别注意的是, String虽然不属于基本类型, 但是String在参数传递过程中的表现与基本类型一致!! 

比较普遍的解释是, String在值传递的时候, 传递的值确实是传的地址, 但是源码中, new 了一个新的String, 接下来的操作都是对这一个new出来的String实体, 因此没有改变原本的String实体, 结果就是String的表现和基本类型一致, 方法外部的String作为参数传递进方法时, 不会被方法改变.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值