Java 之 值传递 引用传递

概念

  • 值传递:指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

  • 引用传递:指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

误区

  1. 通过传递的内容来区分,如果是个值,就是值传递;如果是个引用,就是引用传递。
  2. java 是 引用传递。
  3. 传递的参数如果是普通类型,就是值传递;如果是对象就是引用传递。

举个例子

例子1

public class Test {
	public static void main(String[] args) {
		int num1 = 10;
		int num2 = 20;
		temp(num1, num2);
		System.out.println("main() num1 = " + num1);
		System.out.println("main() num2 = " + num2);
	}

	public static void temp(int a, int b) {
		int temp = a;
		a = b;
		b = temp;
		System.out.println("temp() a = " + a);
		System.out.println("temp() b = " + b);
	}
}

## 输出结果为:
	temp() a = 20
	temp() b = 10
	main() num1 = 10
	main() num2 = 20

为什么temp方法输出的值进行了交换,而main输出的却没交换?

1.对于基本数据类型来说,使用的是值传递。即 temp=a;a=b;b=temp; 这种情况。
2.但在函数方法中,即实参传递给形参这种情况下,首先把实参复制了一份,并复制给形参。也就是得到的形参是实参的备份。
3.通过对复制出来的备份进行值的交换,并不会影响原来的数值。这也就说明了为什么temp方法输出的值进行了交换,而main输出的却没交换

例子2

public class Test {
	
	public static void main(String[] args) {
		Student t1 = new Student("张三", 18);
		Student t2 = new Student("李四", 19);
		temp(t1, t2);
		System.out.println("main() t1:" + t1);
		System.out.println("main() t2:" + t2);
	}

	private static void temp(Student t1, Student t2) {
		Student t = t1;
		t1 = t2;
		t2 = t;
		System.out.println("temp() t1:" + t1);
		System.out.println("temp() t2:" + t2);
	}
}
class Student {
	String name;
	int age;

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

	@Override
	public String toString() {
		return "Test {" +
				"name='" + name + '\'' +
				", age=" + age +
				'}';
	}
}
## 输出结果为:
	temp() t1:Test {name='李四', age=19}
	temp() t2:Test {name='张三', age=18}
	main() t1:Test {name='张三', age=18}
	main() t2:Test {name='李四', age=19}

原因同例子1,本例子是将实参的地址复制了一份,并赋值给形参,然后进行交换,使其改变指向。
但是,注意: 这并不是引用传递,在Java里只能叫传递了对象的引用,本质上是传递了对象的引用(地址)的副本,这也算值传递。

若将交换函数改成如下代码,则成功进行交换

public class Test {

	public static void main(String[] args) {
		Student t1 = new Student("张三", 18);
		Student t2 = new Student("李四", 19);
		change(t1,t2);
		System.out.println("main() t1:" + t1);
		System.out.println("main() t2:" + t2);
	}
	private static void change(Student t1, Student t2) {
		Student t = new Student("王五",20);
		t.name=t1.name;
		t.age = t1.age;
		t1.name= t2.name;
		t1.age= t2.age;
		t2.name= t.name;
		t2.age = t.age;

		System.out.println("change() t1:" + t1);
		System.out.println("change() t2:" + t2);
	}

	private static void temp(Student t1, Student t2) {
		Student t = t1;
		t1 = t2;
		t2 = t;
		System.out.println("temp() t1:" + t1);
		System.out.println("temp() t2:" + t2);
	}
}
class Student {
	String name;
	int age;

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

	@Override
	public String toString() {
		return "Test {" +
				"name='" + name + '\'' +
				", age=" + age +
				'}';
	}
}
## 输出结果为:
	change() t1:Test {name='李四', age=19}
	change() t2:Test {name='张三', age=18}
	main() t1:Test {name='李四', age=19}
	main() t2:Test {name='张三', age=18}

总结

  • 值传递是指在调用函数时将实际参数复制一份传递到函数中;引用传递是指在调用函数时将实际参数的引用直接传递到函数中。

  • Java中的基本数据类型是值传递。针对 八种基本数据类型来讲,当以参数形式传递给方法是,会把值copy一个新的变量,供该方法内使用。两个变量互不影响

  • 对于八种基本数据类型的包装类和String 他们是不可变对象 ,所以也会以值传递的形式传进方法内。比如:Integer 类中 有final修饰

  • 很多人却误认为Java中的对象传递是引用传递。之所以会有这个误区,主要是因为Java中的变量和对象之间是有引用关系的。Java语言中是通过对象的引用来操纵对象的。所以,很多人会认为对象的传递是引用的传递。

  • Java对象的传递,是通过复制的方式把引用关系传递了,如果我们没有改引用关系,而是找到引用的地址,把里面的内容改了,是会对调用方有影响的,因为大家指向的是同一个共享对象。

  • 引用传递:对于引用数据类型,会把对象的引用传入方法内,会相互影响.

  • 引用传参,传的是对象的地址,通过地址访问地址指向的内存空间lian

链接

我要彻底给你讲清楚,Java就是值传递,不接受争辩的那种!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值