价值,参考变量
在以下示例中,我对理解Java的“传值”操作存在问题:
public class Numbers {
static int[] s_ccc = {7};
static int[] t_ccc = {7};
public static void calculate(int[] b, int[] c) {
System.out.println("s_ccc[0] = " + s_ccc[0]); // 7
System.out.println("t_ccc[0] = " + t_ccc[0]); // 7
b[0] = b[0] + 9;
System.out.println("nb[0] = " + b[0]); // 16
c = b;
System.out.println("c[0] = " + c[0] + "n"); // 16
}
public static void main(String[] args) {
calculate(s_ccc, t_ccc);
System.out.println("s_ccc[0] = " + s_ccc[0]); // 16
System.out.println("t_ccc[0] = " + t_ccc[0]); // 7
}
}
我知道,因为s_ccc是一个引用变量,所以当我将它提供给方法calculate()并对方法中的元素进行一些更改时,甚至在我离开方法之后,这些更改仍然保留。 我认为这应该与t_ccc一致。 它又是一个引用变量,我将它提供给calculate()方法,并且在该方法中,将引用改为t_ccc,使其成为s_ccc的引用。 现在t_ccc应该是一个指向一个数组的引用变量,它有一个int类型的元素等于16。但是当方法calculate()离开时,t_ccc似乎指向它的旧对象。 这是为什么发生? 这种变化是不是也应该留下来呢? 毕竟它是一个参考变量。
问候
关于Java在先前的问题中如何传递变量,有一个扩展的讨论:“Java是否通过引用传递?”。 Java确实通过值来传递对象引用。
在你的代码中,数组的引用(它们是对象)被传入calculate()
。 这些引用是通过值传递的,这意味着对b
和c
的值的任何更改仅在方法内可见(它们实际上只是s_ccc
和t_ccc
的副本)。 这就是为什么main()
t_ccc
从不受影响的原因。
为了强化这个概念,一些程序员将方法参数声明为final
变量:
public static void calculate(final int[] b, final int[] c)
现在,编译器甚至不允许你改变b
或c
的值。 当然,这个缺点是你不能在你的方法中方便地操纵它们。
这是理解它的一种简单方法。
Java总是传递参数的副本。 如果参数是基本类型(例如整数),则被调用的方法获取原始值的副本。 如果参数是一个引用类型,那么被调用的方法会获取引用的副本( 而不是引用的副本)。
当你的main
方法开始时,每个s_ccc
和t_ccc
指向一个不同的数组。 情况就是这样,括号表示变量,方括号表示实际的数组结构:
(s_ccc) ---> [7]
(t_ccc) ---> [7]
假设你的意思是calculate(s_ccc, t_ccc)
,那么在calculate
方法的开始处:
(s_ccc) ---> [7] <---(b)
(t_ccc) ---> [7] <---(c)
当地b
和c
分别是全局变量s_ccc
和t_ccc
拷贝。
仍然在calculcate
内, b[0] = b[0] + 9
完成后:
(s_ccc) ---> [16] <---(b)
(t_ccc) ---> [7] <---(c)
b
引用的数组中的零(仅)位置已被修改。
calculate
的赋值c = b
会产生这种情况:
(s_ccc) ---> [16] <---(b)
^------(c)
(t_ccc) ---> [7]
本地参考变量c
现在包含与b
相同的参考。 这对全局引用变量t_ccc
没有影响,它仍然与以前一样引用相同的数组。
calculate
退出时,其局部变量(在图的右侧)消失。 全局变量(左侧)未用于calculate
,因此它们不受影响。 最后的情况是:
(s_ccc) ---> [16]
(t_ccc) ---> [7]
c_ccc
和t_ccc
都没有改变; 每个仍然指向与之前calculate
相同的数组。 调用calculate
使用对该数组的复制引用(在b
)更改了s_ccc
引用的数组的内容。
局部变量c
作为t_ccc
的副本而开始,并在calculate
内部进行了操作,但它既不改变t_ccc
本身,也不改变它的参考数据。
该方法按值接收变量。 这些值不能被改变(就方法的调用者而言),但是它们中包含的值可以(如果它是一个对象,或者在这种情况下是一个数组)。
因此,当您更改数组内的值b [0]时,可以在方法外看到更改。 但是这条线
c = b;
会改变方法内部的c值,但这种改变不会在方法之外看到,因为c的值是按值传递的。
链接地址: http://www.djcxy.com/p/20703.html