use*_*155 2 java reference pass-by-value
在以下示例中,我对理解Java的"pass-by-value"操作有疑问:
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
}
}
Run Code Online (Sandbox Code Playgroud)
我知道因为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).这就是为什么t_ccc在main()从来没有受到影响.
为了强化这个概念,一些程序员将方法参数声明为final变量:
public static void calculate(final int[] b, final int[] c)
Run Code Online (Sandbox Code Playgroud)
现在,编译器甚至不允许您更改b或的值c.当然,这样做的缺点是你不能再在方法中方便地操作它们.
这是一种理解它的简单方法.
Java总是传递参数的副本.如果参数是基本类型(例如整数),则被调用的方法获取原始值的副本.如果参数是引用类型,则被调用的方法获取引用的副本(不是引用的事物的副本).
当你的main方法开始,每个的s_ccc和t_ccc指的是不同的阵列.这种情况下,括号表示变量,方括号表示实际的数组结构:
(s_ccc) ---> [7]
(t_ccc) ---> [7]
Run Code Online (Sandbox Code Playgroud)
假设你的意思是calculate(s_ccc, t_ccc),那么在calculate方法的开头:
(s_ccc) ---> [7] <---(b)
(t_ccc) ---> [7] <---(c)
Run Code Online (Sandbox Code Playgroud)
当地人b和c是副本全局的s_ccc和t_ccc分别.
完成calculcate之后,仍然在内b[0] = b[0] + 9:
(s_ccc) ---> [16] <---(b)
(t_ccc) ---> [7] <---(c)
Run Code Online (Sandbox Code Playgroud)
所引用的数组中b的零(仅)位置已被修改.
c = b内部任务calculate产生这种情况:
(s_ccc) ---> [16] <---(b)
^------(c)
(t_ccc) ---> [7]
Run Code Online (Sandbox Code Playgroud)
本地引用变量c现在包含与之相同的引用b.这对全局引用变量没有影响t_ccc,它仍然引用与以前相同的数组.
当calculate退出时,它的局部变量(上图的右侧)消失.全局变量(在左侧)未使用calculate,因此它们不受影响.最后的情况是:
(s_ccc) ---> [16]
(t_ccc) ---> [7]
Run Code Online (Sandbox Code Playgroud)
既c_ccc没有t_ccc改变,也没有改变; 每个仍然引用与以前相同的数组calculate.调用使用对该数组的复制引用(in )calculate更改了引用的数组的内容.s_cccb
局部变量c开始作为一个副本t_ccc,并操纵之内calculate,但没有改变t_ccc自己,也不它引用的数据.
该方法按值接收变量.这些值不能更改(只要方法的调用者看到),但它们中包含的值可以(如果它是一个对象,或者在这种情况下是一个数组).
因此,当您更改数组中的值b [0]时,可以在方法外部看到更改.但行
c = b;
Run Code Online (Sandbox Code Playgroud)
将更改方法内部的c值,但在方法外部不会看到该更改,因为c的值是按值传递的.
该行calculate(s_ccc, s_ccc);表示您实际上没有对t_ccc做任何事情.但是,如果此行读取calculate(s_ccc, t_ccc);的效果仍然相同.
这是因为您在此处为c c = b;
分配了一个新值:当为引用参数赋值时,引用将丢失.
这是通过引用变量更改和分配新值之间的区别.
| 归档时间: |
|
| 查看次数: |
8750 次 |
| 最近记录: |