java值传递还是引用传递

参考 https://www.zhihu.com/question/31203609
参考 http://www.cnblogs.com/xwdreamer/archive/2012/04/01/2428857.html
参考 https://www.cnblogs.com/binyue/p/3862276.html

什么是值传递,什么是引用传递

  • 值传递(pass by value): 是指在方法调用的过程中,是将参数copy一份传递到函数中,在函数中对参数进行修改,将不会影响到实际的参数。
  • 引用传递(pass by reference): 是指在方法调用过程中,是将参数的实际地址传递到函数中,在函数中对参数进行修改,会影响到实际参数。

那么java到底是值传递还是引用传递呢? 在业界有很多种说法,在开撕之前,我们先回忆下java的内存机制。

Java的内存机制

Java 把内存划分成两种:一种是栈内存,另一种是堆内存

这种分法比较粗浅,java内存区域实际远比这个复杂。
这种分发比较流行只能说明大多数程序员最关注的、与内存分配关系最密切的内存区域就是这两块。

  • 基本类型的变量和对象的引用变量都是在函数的栈内存中分配
  • 堆内存用来存放由new创建的对象和数组。

例: 对象创建

class Person{
	public String name;
	public int age;

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
}

public class PassByWhat {
	public static void main(String[] args) {	
		int num = 9 ;
		Person person  = new Person("trump", 73);
	}
}

此时他们在内存中的分布,如下图:
![在这里插入图片描述](ht
例-赋值运算符"="的作用

	public static void main(String[] args) {

		int num = 9 ;
		Person person  = new Person("trump", 73);

		num = 8 ;
		person = new Person("hillary", 72);
}

此时他们在内存中的分布,如下图:
在这里插入图片描述

  • 对于基本类型 num ,赋值运算符会直接改变变量的值,原来的值被覆盖掉。
  • 对于引用类型 person,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。

pass_by_what ?

例:验证

public class PassByWhat {

	public static void main(String[] args) {
		int num = 1;
		f1(num);
		System.out.println("f1()修改后:num="+num);

		Person person = new Person("trump", 73);
		f2(person);
		System.out.println("f2()修改后:"+person);


		f3(person);
		System.out.println("f3()修改后:"+person);
	}

	static void f1(int n) {
		n = -999;
	}

	static void f2(Person p){
		p.age =  66;
	}

	static void f3(Person p){
		p = new Person("hillary", 72);
	}
}

运行结果:
在这里插入图片描述

  • f1(int):修改未起作用 — 说明是值传递
  • f2(Person):修改起作用 — 说明是引用传递
  • f3(Person): 修改未起作用 — 说明是值传递

从上述的结果分析,得出一个结论java似乎既不是我们之前理解的那种值传递也不是引用传递.
那么java到底pass_by_what ?

pass_by_what

实参和形参的概念
在这里插入图片描述

f2()为什么修改成功
在调用方法f2()时,实际参数的引用地址(person:0x123)被传递给方法中相对应的形式参数(p:0x123):
在这里插入图片描述
执行完f2()逻辑p.age = 66;之后,p的引用地址值并未发生改变。
在这里插入图片描述
在方法执行中,形参和实参指向同一块内存地址,方法执行中对引用的操作将会影响到实际对象。

f3()为什么修改不成功

在这里插入图片描述
在方法执行中,形参(0x123)和实参(0x789)指向的不是同一块内存地址,所以方法执行的结果不会想象到实参。

结论

  • 基本数据类型传值,对形参的修改不会影响实参;
  • 引用类型传引用
    • 形参和实参指向同一个内存地址,所以对参数的修改会影响到实际的对象;
    • 形参和实参指向不同内存地址的,则对参数的修改不会影响到实际的对象;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值