关于Java的值传递和引用传递

1 篇文章 0 订阅
1 篇文章 0 订阅

结论:

1. 对于值传递,如int, long等基本类型,不管传入方法后怎么修改,都改变不了方法外面的值。

2. 对于引用传递,如果传入方法后指向了一个新的对象,那么无论怎么修改也改变不了方法外面的对象。

    如果传入方法后没有指向新对象,直接操作,就会改变方法外面的对象,因为这是在操作同一个对象。


来看一段测试源码:

package aa;

public class TestObjDelivery {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//Test 1
		String srcStr = new String("src");
		print(srcStr);
		changeStr(srcStr);
		print(srcStr);
		
		//Test 2
		int srcInt = 10;
		print("int: " + srcInt);
		changeInt(srcInt);
		print("int: " + srcInt);
		
		//Test 3
		ObjTest srcObj = new ObjTest();
		srcObj.setInt(15);
		srcObj.setString("srcObjStr");
		print(srcObj.toString());
		changeObj(srcObj);
		print(srcObj.toString());
		
		//Test 4
		StringBuilder srcSB = new StringBuilder("src");
		print(srcSB.toString());
		changeSB(srcSB);
		print(srcSB.toString());
		

	}
	
	public static void changeSB(StringBuilder decSB){
		decSB.delete(0, decSB.length()).append("dec");
	}
	
	public static void changeStr(String decStr){
//		decStr = new String("dec");
		decStr = "dec";
	}
	
	public static void changeInt(int decInt){
		decInt = 9;
	}
	
	/**
	 * Case1. new ObjectTest() is to change the direction of decObj.
	 * Case2. Only set properties for decObj is operating on the initial Object.
	 */
	public static void changeObj(ObjTest decObj){
//		decObj = new ObjTest();
		decObj.setInt(14);
		decObj.setString("decObjStr");
	}
	
	public static void print(String str){
		System.out.println(str);
	}

}

输出结果:

src
src
int: 10
int: 10
The string is: srcObjStr, the int is: 15
The string is: decObjStr, the int is: 14
src
dec

对于上述测试,这里有一些说明:

Test 1 引用传递: 这是测试一个字符串【srcStr】传入方法【changeStr(String decStr)】后重新赋值【decStr = new String("dec")】,外面的字符串对象【srcStr】是否被改变? 答案是否。

srcStr 传给decStr其实传递的是引用,这个引用可以说是一个地址,指向都是同一个内存空间块(真正存储"src"的地方)。方法changeStr(String decStr)内,不管是通过new String("dec")赋值,还是通过 ="dec"赋值,Java虚拟机都是创建一个新的String对象,即开辟了一块新的内存空间,把地址赋给decSrc,这个时候,decSrc指向的就是新的对象了,所以跟外部的srcStr没有半毛钱关系。


Test 2 值传递:这是测试一个整型数值【srcInt】传入方法【changeInt(int decInt)】后重新赋值【decInt = 9】,外面的整型数值【srcInt】是否被改变?答案是否。

srcInt传递给decInt是一个值,但是,这是一个拷贝出来的值。srcInt和decInt分别代表了不同的内存块。所以传入方法后,不管怎么修改decInt,都改不了srcInt。


Test 3 引用传递:这是测试一个对象【srcObj】传入方法【changeObj(ObjTest decObj)】后重新赋值,外面的对象【srcObj】是否被改变?答案是如果创建新对象就否,如果直接修改就是。这个是为了跟Test 1做进一步分析。

srcObj传递给decSrc是一个引用,同Test 1。这次我们关注方法changeObj(ObjTest decObj)内部的不同实现所带来不同的结果:

* 如果内部有decObj = new ObjTest(),然后再对decObj进行操作,其实这个时候decObj指向的是新的对象,所以对新对象操作不会影响到srcObj所指向的对象。

* 如果内部没有decObj = new ObjTest(),而是直接对decObj进行操作,这个时候操作的就是srcObj所指向的对象,所以会影响到srcObj。


Test 4 引用传递:这是测试一个StringBuilder对象【srcSB】传入方法【changeSB(StringBuilder decSB)】后在原有空间赋值【decSB.delete(0, decSB.length()).append("dec")】,外面的StringBuilder对象是否被改变?答案是否。这是为了跟Test 1和Test 3做扩展分析。

原理都一样,对象传递的就是引用。

* 如果new StringBuilder()赋值给decSB的话,这就是一个新对象。不会改变外面的srcSB。

* 像测试方法里面的做法,就是为了在原有的空间操作字符串。自然会改变外面的srcSB。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值