【问题标题】:I cant figure out how this void method works我不知道这个 void 方法是如何工作的
【发布时间】:2012-10-16 08:32:00
【问题描述】:

我的代码是:

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

【问题讨论】:

    标签: java arrays void


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 你应该更清楚,数组仍然是传值,它的值只是对内存中某个地方的引用。
    【解决方案2】:
     if ( z.length >= 1   ) {  
            z[0] = 100;  
        }
    

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

    所以,当您执行以下代码时会发生这种情况:

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

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

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 更准确地说,Java 中只有 Pass-by-value。它不是“数组通过引用传递”。它是“传递引用/指向数组的指针,并且是按值传递”
      【解决方案4】:

      当您将变量传递给 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
                          -------------- 
      

      【讨论】:

        【解决方案5】:
        method1(a,  b[0], c);
        

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

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

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

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

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

                 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.
        

        【讨论】:

          【解决方案6】:

          为什么不改变?

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

          【讨论】:

            【解决方案7】:

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

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

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

            【讨论】:

              猜你喜欢
              • 2015-09-14
              • 2017-01-28
              • 1970-01-01
              • 1970-01-01
              • 2014-04-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多