Java采用按值传递的方式,而不是按引用传递

介绍

许多Java程序员都对Java是按值传递还是按引用传递存有疑问。本文总结了为什么Java始终是按值传递的原因。

首先,”pass by value” 和 “pass by reference” 是什么意思?

  • Pass by value: The method parameter values are copied to another variable and then the copied object is passed to the method. The method uses the copy.
  • Pass by reference: An alias or reference to the actual parameter is passed to the method. The method accesses the actual parameter.

通常,这些术语的困惑是由于Java中对象引用的概念造成的。从技术上讲,Java始终是值传递,因为即使变量可能保存一个对象的引用,但那个对象引用是一个代表内存中对象位置的值。因此,对象引用是按值传递的。

无论是引用数据类型还是基本数据类型都是按值传递的。了解更多关于Java中的数据类型。

除了理解数据类型,还需要理解Java的内存分配,因为引用数据类型和原始数据类型存储方式不同很重要。

展示传值方式

以下示例展示了Java中值是如何传递的。

这个示例程序使用了下面的类

public class Balloon {

	private String color;

	public Balloon() {}
	
	public Balloon(String c) {
		this.color = c;
	}
	
	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
}

以下示例程序使用了一个通用方法swap(),该方法可以交换两个变量的值。另一个方法changeValue()试图改变变量的值。

public class Test {

	public static void main(String[] args) {

		Balloon red = new Balloon("Red"); // memory reference = 50
		Balloon blue = new Balloon("Blue"); // memory reference = 100
		
		swap(red, blue);
		System.out.println("After the swap method executes:");
		System.out.println("`red` color value = " + red.getColor());
		System.out.println("`blue` color value = " + blue.getColor());
		
		changeValue(blue);
		System.out.println("After the changeValue method executes:");
		System.out.println("`blue` color value = " + blue.getColor());
		
	}

	// Generic swap method
	public static void swap(Object o1, Object o2){
		Object temp = o1;
		o1 = o2;
		o2 = temp;
	}

	private static void changeValue(Balloon balloon) { // balloon = 100
		balloon.setColor("Red"); // balloon = 100
		balloon = new Balloon("Green"); // balloon = 200
		balloon.setColor("Blue"); // balloon = 200
	}

}

当您执行示例程序时,您将得到以下输出结果。

Output

After the swap method executes: ‘red’ color value = Red ‘blue’ color value = Blue After the changeValue method executes: ‘blue’ color value = Red

输出结果显示swap()方法没有交换原始对象的颜色值。这有助于显示Java是按值传递的,因为swap()方法只对原始对象引用值的副本进行操作。

这个swap()方法的测试可以与任何编程语言一起使用,以检查它是按值传递还是按引用传递。

解释了swap()方法的示例。

当你使用new运算符创建一个类的实例时,对象被创建并且变量包含了对象保存在内存中的位置。

Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");

当swap()方法执行时,下面是一步一步的解释:

  • Assume that red is pointing to memory location 50 and blue is pointing to memory location 100, and that these are the memory locations of both Balloon objects.
  • When the class calls the swap() method with the red and blue variables as arguments, two new object variables, o1 and o2, are created. o1 and o2 also point to memory locations 50 and 100 respectively.
  • The following code snippet explains what happens within the swap() method:
    public static void swap(Object o1, Object o2) { // o1 = 50, o2 = 100
    Object temp = o1; // assign the object reference value of o1 to temp: temp = 50, o1 = 50, o2 = 100
    o1 = o2; // assign the object reference value of o2 to o1: temp = 50, o1 = 100, o2 = 100
    o2 = temp; // assign the object reference value of temp to o2: temp = 50, o1 = 100, o2 = 50
    } // method terminated
  • The values of o1 and o2 are swapped, but because the values are copies of the red and blue memory locations, there is no change to the values of the red and blue color values.

由于变量包含对对象的引用,所以常常会错误地认为你是传递了引用而Java是按引用传递的。然而,实际上你是传递了引用的副本,因此是按值传递。

解释了changeValue()方法的示例

例程中的下一个方法会改变blue变量所引用的对象的颜色值。

private static void changeValue(Balloon balloon) { // balloon = 100
	balloon.setColor("Red"); // balloon = 100
	balloon = new Balloon("Green"); // balloon = 200
	balloon.setColor("Blue"); // balloon = 200
}

这是changeValue()方法内部所发生的一步步的详细过程解析:

  • The class calls the changeValue() method on the blue variable that references memory location 100. The first line creates a reference that also points to memory location 100. The color value of the object at memory location 100 is changed to “Red”.
  • The second line creates a new object (with color value “Green”). The new object is at memory location 200. Any further methods executed on the balloon variable act upon the object at memory location 200, and don’t affect the object at memory location 100. The new balloon variable overwrites the reference created in line 1 and the balloon reference from line 1 is no longer accessible within this method.
  • The third line changes the color value of the new Balloon object at memory location 200 to “Blue”, but does not affect the original object referenced by blue at memory location 100. This explains why the final line of the example program output prints blue color value = Red, which reflects the change from line 1.

结论

在本篇文章中,您了解了为什么Java是按值传递的。请继续学习更多Java教程来加深您的学习。

广告
将在 10 秒后关闭
bannerAds