介绍
许多Java程序员质疑Java是否是 pass by value 或 pass 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是通过价值的。