价值,参考变量

在以下示例中,我对理解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() 。 这些引用是通过值传递的,这意味着对bc的值的任何更改仅在方法内可见(它们实际上只是s_ccct_ccc的副本)。 这就是为什么main() t_ccc从不受影响的原因。

为了强化这个概念,一些程序员将方法参数声明为final变量:

public static void calculate(final int[] b, final int[] c) 

现在,编译器甚至不允许你改变bc的值。 当然,这个缺点是你不能在你的方法中方便地操纵它们。


这是理解它的一种简单方法。

Java总是传递参数的副本。 如果参数是基本类型(例如整数),则被调用的方法获取原始值的副本。 如果参数是一个引用类型,那么被调用的方法会获取引用的副本( 而不是引用的副本)。

当你的main方法开始时,每个s_ccct_ccc指向一个不同的数组。 情况就是这样,括号表示变量,方括号表示实际的数组结构:

(s_ccc) ---> [7]
(t_ccc) ---> [7]

假设你的意思是calculate(s_ccc, t_ccc) ,那么在calculate方法的开始处:

(s_ccc) ---> [7]  <---(b)
(t_ccc) ---> [7]  <---(c)

当地bc分别是全局变量s_ccct_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_ccct_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

上一篇: value, reference variables

下一篇: String is immutable. What exactly is the meaning?