Java 是按值传递,而不是按引用传递

介绍

许多Java程序员质疑Java是否是 pass by valuepass by reference. 本文概述了为什么Java总是通过值。

首先,通过价值和通过参考意味着什么?

  • 通过值:将方法参数值复制到另一个变量,然后将复制对象传递到方法中。

通常,围绕这些术语的混淆是Java中的对象引用概念的结果,从技术上讲,Java总是通过值,因为即使变量可能包含对象的引用,这个对象引用是代表对象在内存中的位置的值。

参考数据类型和原始数据类型都是通过值传递的。 了解有关 Java 中的数据类型的更多信息。

除了了解数据类型外,了解Java中的记忆分配(/community/tutorials/java-heap-space-vs-stack-memory)也很重要,因为参考数据类型和原始数据类型存储不同。

通过价值证明

下面的示例展示了如何在Java中传输值。

示例程序使用以下类:

 1public class Balloon {
 2
 3    private String color;
 4
 5    public Balloon() {}
 6    
 7    public Balloon(String c) {
 8    	this.color = c;
 9    }
10    
11    public String getColor() {
12    	return color;
13    }
14
15    public void setColor(String color) {
16    	this.color = color;
17    }
18}

下面的示例程序使用了一种通用方法,‘swap()’,用于交换两个变量,另一种方法,‘changeValue()’,试图更改变量值。

 1public class Test {
 2
 3    public static void main(String[] args) {
 4
 5    	Balloon red = new Balloon("Red"); // memory reference = 50
 6    	Balloon blue = new Balloon("Blue"); // memory reference = 100
 7    	
 8    	swap(red, blue);
 9    	System.out.println("After the swap method executes:");
10    	System.out.println("`red` color value = " + red.getColor());
11    	System.out.println("`blue` color value = " + blue.getColor());
12    	
13    	changeValue(blue);
14    	System.out.println("After the changeValue method executes:");
15    	System.out.println("`blue` color value = " + blue.getColor());
16    	
17    }
18
19    // Generic swap method
20    public static void swap(Object o1, Object o2){
21    	Object temp = o1;
22    	o1 = o2;
23    	o2 = temp;
24    }
25
26    private static void changeValue(Balloon balloon) { // balloon = 100
27    	balloon.setColor("Red"); // balloon = 100
28    	balloon = new Balloon("Green"); // balloon = 200
29    	balloon.setColor("Blue"); // balloon = 200
30    }
31
32}

当您运行示例程序时,您将获得以下输出:

1[secondary_label Output]
2After the swap method executes:
3'red' color value = Red
4'blue' color value = Blue
5After the changeValue method executes:
6'blue' color value = Red

输出显示swap()方法没有交换原始对象的颜色值,这有助于显示Java是通过值的,因为swap()方法只对原始对象参考值的副本产生作用。

这种swap()方法测试可以用任何编程语言来检查它是否通过值或通过参考。

示例 swap() 方法 解释

当您使用运算符创建类的实例时,将创建对象,而变量包含存储对象的内存位置。

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

以下是swap()方法执行时会发生什么的步骤式分解:

  • 假设 " 红色 " 指记忆位置50, " 蓝色 " 指记忆位置100,这些是 " 巴洛翁 " 两种物体的记忆位置。 ( -- ( )* 当该类将 " swap() " 方法称为 " 红色 " 和 " 蓝色 " 变量作为参数时,将产生两个新的对象变量,即o1'和o2'。 o1'和o2'也分别指50和100个记忆地点。 () ( )* 以下代码片段解释"swap ()"方法范围内发生的情况: QQjava 公共静态空置交换(Object o1, Object o2) { // o1 = 50,o2 = 100 对象临时=o1;//将对象参考值o1指定为:临时=50,o1=50,o2=100(- )o1=o2;//将对象参考值o2指定为:临时=50,o1=100,o2=临时;/将对象参考值指定为:临时=50,o1=100,o2=50(- )}//方法终止(- )(- )** " o1 " 和 " o2 " 的值是互换的,但由于这些值是 " 红色 " 和 " 蓝色 " 记忆位置的复制品, " 红色 " 和 " 蓝色 " 颜色值的值没有变化。 (_) (英语)

由于变量包含对象的引用,所以假设您正在通过引用,而Java是通过引用是一个常见的错误,但是,您正在通过一个值,这是一个副本的引用,因此它是通过的值。

示例 changeValue() 方法 解释

示例程序中的下一种方法更改了由蓝色变量引用的对象的颜色值:

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

以下是changeValue()方法中发生的事情的步骤式分解:

第一行创建一个引用,也指向记忆位置100的引用。在记忆位置100的对象的颜色值被更改为红色 第二行创建了一个新的对象(有颜色值绿色)。新对象在记忆位置200。在记忆位置200上执行的任何进一步方法都对记忆位置200的对象起作用,而不会影响记忆位置100上的对象。在记忆位置的新气球变量重写了第1行创建的引用,而从第1行的气球引用不再在该方法中可用( _)第三行改变了记忆位置200上的新气球对象的颜色值到蓝色,但不会影响由蓝色在记忆位置100

结论

在这篇文章中,你了解了为什么Java是通过价值的。

Published At
Categories with 技术
comments powered by Disqus