Java中的值传递,为什么是值传递?

本文部分内容引用自Java核心技术++卷1, mm:mwz0

Java中的值传递

  • 1.参数传递
  • 2.举例修改基本数据类型参数
  • 3.举例修改对象参数
  • 4.为什么Java是值传递
  • 5.总结

1.参数传递

首先回顾一下在程序设计语言中有关将参数传递给方法(或参数)的一些术语。按值调用(call by value)表示方法接收的是调用者提供的值。而按引用调用(call byreference)表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。“按····调用”(call by)是一个标准的计算机科学术语,他用来描述各种程序设计语言(不只是java)中方法参数的传递方式。

2.举例修改基本数据类型参数

Java语言总是采用按值调用。也就是说,方法得到的是所有值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。
例如,看下述的调用:

	double percent = 10;
	harry.raiseSalary(percent);

不用理会上述raiseSalary方法的具体实现,在方法调用后,percent的值还是10。

下面在对上述情况进行研究。假定一个方法试图将一个参数值增加3倍:

	public static void tripleValue(double x){
		x =  3 * x;
	}
	//然后调用这个方法:
	double percent = 10;
	tripleValue(percent);

==但是上述方法并没有将percent 变成当前值的3倍。调用这个方法后percent的值还是10。==下面看一下具体的执行过程:

  1. x 被初始化为percent值的一个拷贝(也就是10)。
  2. x 被乘以3后等于30。但是percent仍然是10(如下图所示)。
  3. 这个方法结束后,参数变量x 不再使用。
    然而,方法参数共有两种类型:
    a.基本数据类型。
    b.对象引用。
    Java中的值传递,为什么是值传递?_第1张图片

3.举例修改对象参数

根据上述事例看到,一个方法不可能修改一个基本数据类型的参数(数值型或布尔型)。而对象引用作为参数就不同了,可以很容易利用下面的方法进行实现修改。

	public class Employee {
 		private String name; 
 		private double salary;

		public Employee(String n, double s) {
			name = n;
			salary = s ;
		}
		 //省略get set方法
	}

	public static void tripleSalary(Employee x){
		x.raiseSalary(200);//将salary提高200倍
	}
	

当调用:

	harry = new Employee(...);
	tripleSalary(harry);

方法时,具体的执行过程为:

  1. x 被初始化微harry值的拷贝,这里表示是一个对象的引用。
  2. raiseSalary方法应用于这个对象引用。x和harry同时引用那个Employee对象的salary属性提高了200倍。
  3. 方法结束后,参数变量 x 不再使用。当然,对象变量harry继续引用那个 salary 增至 200倍的 Employee 对象(如下图所示)。
    Java中的值传递,为什么是值传递?_第2张图片

格局上述事例看到,实现一个改变对象参数状态的方法并不一定是一件难事。方法得到的是对象引用的拷贝,对象引用及其他的拷贝同事引用同一个对象。

==很多程序设计语言(特别是, C++ 和 Pascal) 提供了两种参数传递的方式:值调用和引用调用。很多人认为 Java 程序设计语言对对象采用的是引用调用,实际上, 这种理解是不对的。==由于这种误解具有一定的普遍性,所以下面给出一个反例来详细地阐述一下这个问题

4.为什么Java是值传递

首先,编写一个交换两个雇员对象的方法:

	public static void swap(Employee x, Employee y){
		Employee temp = x;
		x = y;
		y = temp;
	}

如果Java对象采用的是按引用调用,那么这个方法就应该能够实现交换数据的效果:

	Employee a = new Employee("Alice", . . .);
	Employee b = new Employee("Bob", . . .);
	swap(a, b);

但是,方法并没有改变存储在变量 a 和 b 中的对象引用。swap 方法的参数 x 和 y 被初始化为两个对象引用的拷贝,这个方法交换的是这两个拷贝。
在方法结束时参数变量 x 和 y 被丢弃了。原来的变量 a 和 b 仍然引用这个方法调用之前所引用的对象(如下图所示)。

Java中的值传递,为什么是值传递?_第3张图片这个过程说明:Java语言对对象采用的不是引用传递,实际上是,对象引用是按照值传递的。

5.总结

  • 一个方法不能修改一个基本数据类型的参数(即数值型或布尔型)。
  • 一个方法可以改变一个对象参数的状态。
  • 一个方法不能让对象参数引用一个新的小对象。

你可能感兴趣的:(java基础,java)