我无法弄清楚这种void方法是如何工作的

时间:2012-10-26 04:32:20

标签: java arrays void

我的代码是:

public class MyProgram {
    public void start() {
        int a = 1; 
        int[] b = { 1, 2, 3}; 
        int[] c = { 1, 2, 3}; 

        method1(a,  b[0], c); 

        System.out.println("a   = " + a); 
        System.out.println("b[0]   = " + b[0]); 
        System.out.println("c[0]   = " + c[0]); 
    }

    private  void method1(int x, int y, int[] z) {
        x++; 
        y = 10; 

        if ( z.length >= 1   ) {  
            z[0] = 100;  
        }
        System.out.println(x); 
        System.out.println(y); 
    }
}

输出

a   = 1
b[0]   = 1
c[0]   = 100

我真的不知道为什么只有c [0]发生了变化。

7 个答案:

答案 0 :(得分:3)

private void method1(int x, int y, int[] z)

请注意,int类型是基元,因此它按值传递(值被复制)

int[]类型是一个数组,因此它通过引用传递(对数组的引用被传递)

因此,当您修改int变量时,您正在更改副本 - 它们不会影响该函数范围之外的变量

当您修改数组时,它是通过传入的引用完成的 - 因此更改仍然存在。

答案 1 :(得分:2)

 if ( z.length >= 1   ) {  
        z[0] = 100;  
    }

因为你在这里改变它并且数组通过“引用值”(该引用的另一个副本,仍然指向同一个对象/数组)。

所以,这里发生的是当你执行代码时:

method1(a,  b[0], c); 

它将'c'参考值传递给method1。

method1内,您没有为此参考值副本分配任何new数组,因此对此引用的操作反映在原始数组上。

所以z[0]更新反映在c[0]索引。

答案 2 :(得分:1)

因为数组是通过引用传递的,而其他变量是本地的。

答案 3 :(得分:1)

当您将变量传递给Java中的方法时,您传递其“值”(因为Java仅支持按值传递)。对于“引用类型”变量(如数组和对象),传递其值,但它们的值是对实际存储数据的内存中某个位置的引用。

因此,在method1方法内对数组所做的任何修改都将改变数组的实际内容。

记忆示例:

                    (someplace in memory)
 -------            --------------
|   c   |  ----->   |     1      |   0
 -------            |     2      |   1
                    |     3      |   2
                    -------------- 

当您将c传递给方法时,方法中的参数获取c的'value',它实际上是一个引用或指向内存中存储数组数据的某些空间的指针。您在方法中对c所做的任何更改都将反映在数组中,因为它指向内存中的相同位置。

                    (someplace in memory)
 -------            --------------
|   c   |  ----->   |    100     |   0
 -------            |     2      |   1
                    |     3      |   2
                    -------------- 

答案 4 :(得分:1)

method1(a,  b[0], c);

因为在Java中,所有内容都按值传递,所以前两个参数ab[0]在被调用方法中更改时,对调用方法没有影响。因为,当您更改它时,该值将被更改,原始值保持不变。

但是,第三个参数c是数组的引用。这也是通过价值传递的。因此,当您将其传递给方法时,会生成一个引用副本,并且被调用方法(z)中的参数也指向同一个数组对象。

现在,您使用传递的引用对数组所做的任何更改都将反映在指向该数组的所有引用中。

private  void method1(int x, int y, int[] z)

因此,在此方法中,xy是包含与ab中相同值的不同变量。鉴于,z具有不同的reference地址,指向与原始引用array所指向的相同c对象。

         c[0] c[1] c[2]
         z[0] z[1] z[2] // So, if you change `z[0]`, `a[0]` will also see the change

c ---->  [ 1,   2,   3 ] -> // Any change in the array is reflected in 
          ^                 // both the reference a and z
          |
          |
z --------+

a -> someValue
x -> someValue -> // If we change this, the `someValue` for `a` won't be changed.

答案 5 :(得分:0)

为什么不改变?

c指向一个数组对象。当您将c传递给method1时,c的副本(指针/引用,而不是数组本身)将作为z传递。但是,z仍然指向c指向的同一个数组实例。如果你通过z更改了该数组实例的内容,当然它会在你之后访问c后反映出来。

答案 6 :(得分:0)

方法method1有3个参数,前两个是原始int类型,最后一个是数组类型。 Java不通过引用传递方法参数;它按值传递它们。

基本类型不是对象,因此基本类型的副本将传递给method1

您需要了解Java会复制并按值传递引用,而不是对象。在java中创建对象时,可以通过其引用访问该对象。当你调用method1时,java将要做的是获取对数组的引用,制作该引用的副本并将其传递给method1。这意味着您将有两个指向数组的引用(一个在start方法中,一个在method1方法中)。因此,在method1中进行的任何修改最终都会影响数组,因为method1中使用的引用指向数组