Java值传递(参考自Java核心卷1)

结论

方法不能修改基本数据类型的参数(即数值型或布尔型)。

方法可以改变对象参数的状态。

方法不能让一个对象参数引用一个新的对象。

结论理解

  • 对象是值传递的,两个对象变量a和b存储在栈中,作为参数时,同时引用了存储在堆中的同一个对象,即a和b是对同一个对象的不同引用。此时值传递,传递的是对象变量a在栈中存储的引用的对象在堆中的地址,a和b这两个对象变量存储的地址相同,所以是值传递。
  • 因为a和b是对同一个对象的不同引用,所以可以改变对象参数。
    但方法中,让b引用一个新的对象时,b存储的堆的地址变了,b引用了一个新对象,和a无关,方法结束后,b对象变量被回收。a没有变化。
public class Employee {
	String name;
	public Employee(String naString)
	{
		this.name=naString;
	}
	
	public static void change(Employee x) // doesn't work
	{
	System.out.println("调用前x的地址"+x.toString());
	 x = new Employee("Bob");
	 System.out.println("调用后x的地址"+x.toString());
	}
	
	public static void main(String[] args)  {
		var a=new Employee("Alice");
		System.out.println("调用前a的地址"+a.toString());
		change(a);
		System.out.println("调用后a的地址"+a.toString());
	}
}

在这里插入图片描述

在这里插入图片描述

基本数据类型作为函数参数:方法无法修改基本数据类型的参数

public class Main {
	 public static void tripleValue(double x)  {
	 System.out.println("乘3前x的值:"+x);
	 x=3*x;
	 System.out.println("乘3后x的值:"+x);
	 }

	public static void main(String[] args)  {
		double percent=10;
		System.out.println("调用前percent值:"+percent);
		tripleValue(percent);
		System.out.println("调用后percent值:"+percent);
	}
}

在这里插入图片描述

方法无法修改基本数据类型-分析

在这里插入图片描述
在这里插入图片描述

对象引用作为函数参数:可以改变对象参数状态

public class Employee {
	private double salary;
	public Employee(double sa)
	{
		this.salary=sa;
	}
	
	public void raiseSalary(double ra)
	{
		this.salary+=ra;
	}
	
	
	 public static void tripleValue(Employee x)  {
	x.raiseSalary(200);
	 }

	public static void main(String[] args)  {
		Employee xEmployee=new Employee(100);
		System.out.println("调用前salary值:"+xEmployee.salary);
		Employee.tripleValue(xEmployee);
		System.out.println("调用前salary值:"+xEmployee.salary);
	}
}

在这里插入图片描述

对象引用作为函数参数-分析

在这里插入图片描述

**方法得到的是对象引用的副本,原来的对象引用和这个副本都引用同一个对象。**

Java是值传递,不是引用传递——分析

public class Employee {
	String name;
	public Employee(String naString)
	{
		this.name=naString;
	}
	
	public static void swap(Employee x, Employee y) // doesn't work
	{
	Employee temp = x;
	x = y;
	y = temp;
	}
	
	public static void main(String[] args)  {
		var a=new Employee("Alice");
		var b=new Employee("Bob");
		System.out.println("调用前a,b分别是:"+a.name+"  "+b.name);
		swap(a, b);
		System.out.println("调用后a,b分别是:"+a.name+"  "+b.name);
	}
}

在这里插入图片描述
如果Java对对象采用的是按引用传递,那么这个方法就应该能够实现交换。但 swap方法并没有改变存储在变量a和b中的对象引用
这个过程说明: Java程序设计语言对对象采用的不是按引用调用,实际上,对象引用是按值传递的。
在这里插入图片描述

string对象作为函数参数

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
**实参指向的是一个aaaaa的引用地址,传给了形参,可是形参new了个新的对象,并将新对象的引用地址bbbbb存到了形参中。这并不会影响到实参中存储的aaaaa地址,因为Java中只有值传递,是最纯粹的值拷贝!不是别名不是分身!**

C++的值传递和按引用传递

C++中有按值调用和按引用调用。引用参数标有&符号。例如,可以轻松
地实现 void tripleValue (double& x)方法或 void swap (Employees x, Employees y)方法来修改它
们的引用参数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值