5

我的代码是:

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] 发生了变化。

4

7 回答 7

3

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

注意inttype 是一个原始类型,所以它是按值传递的(值被复制过来)

而且int[]type是一个数组,所以是通过引用传递的(对数组的引用是传递过来的)

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

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

于 2012-10-26T04:35:55.727 回答
2
 if ( z.length >= 1   ) {  
        z[0] = 100;  
    }

因为您在此处更改了它并且数组通过“引用值”传递(此引用的另一个副本,仍然指向相同的对象/数组)。

因此,当您执行以下代码时,会发生以下情况:

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

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

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

因此z[0]更新反映在c[0]索引处。

于 2012-10-26T04:34:17.270 回答
1

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

于 2012-10-26T04:34:04.900 回答
1

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

因此,您在method1方法内部对数组进行的任何修改都会改变数组的实际内容。

内存示例:

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

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

                    (someplace in memory)
 -------            --------------
|   c   |  ----->   |    100     |   0
 -------            |     2      |   1
                    |     3      |   2
                    -------------- 
于 2012-10-26T04:36:31.570 回答
1
method1(a,  b[0], c);

由于在 Java 中,一切都是按值传递的,所以前两个参数ab[0],当在被调用方法中更改时,对调用方法没有影响。因为,当你改变它时,值会改变,而原始值保持不变。

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

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

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

因此,在这种方法中,x和是包含与和y相同值的不同变量。然而,具有不同的地址,指向与原始引用指向的相同对象。abzreferencearrayc

         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.
于 2012-10-26T04:37:10.810 回答
0

为什么它不会改变?

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

于 2012-10-26T04:35:53.247 回答
0

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

原始类型不是对象,因此原始类型的副本将被传递到方法1

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

于 2012-10-26T04:47:23.960 回答