【问题标题】:Understanding Java Arrays了解 Java 数组
【发布时间】:2015-07-23 02:52:34
【问题描述】:

请看下面的代码:

public static void main(String[] args) {
    Random random = new Random();
    int[] array = new int[10];
    Arrays.setAll(array, operand -> random.nextInt(10));
    System.out.println(Arrays.toString(array));
    swap(array, 0, 9);
    System.out.println(Arrays.toString(array));
}

static void swap(int[] array, int i, int j) {
    int temp = array[i]; // pass by value ??
    array[i] = array[j]; // the value of temp doesn't change, why?
    array[j] = temp; // temp == array[i]
}

swap 方法中究竟发生了什么?

我需要一个完整的解释和一个低级。

编辑:

好的,让我再举一个例子:

public class StringHolder {

    private String value;

    public StringHolder(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return getValue();
    }

}

主要方法:

public static void main(String[] args) {
    StringHolder[] holders = new StringHolder[]{new StringHolder("string 1")};
    StringHolder tmp = holders[0];
    holders[0].setValue("string 2");
    System.out.println(tmp);
    System.out.println(holders[0]);
}

输出:

string 2
string 2

根据@chokdee 的回答,tmp 是一个新变量,并且拥有自己的内存...

但是当我们对原始变量 (holder[0]) 应用更改时,它也会影响 tmp

另一个例子:

public static void main(String[] args) {
    StringHolder[] holders = new StringHolder[]{new StringHolder("string 1")};
    StringHolder tmp = holders[0];
    holders[0] = new StringHolder("string 2");
    System.out.println(tmp);
    System.out.println(holders[0]);
}

输出:

string 1
string 2

提前致谢。

【问题讨论】:

  • 这感觉很像是一道作业题……
  • 你确定吗?我记得大学时代有一个几乎与家庭作业相同的问题:)
  • 我需要一个完整的解释和一个低级。当然,这不是家庭作业?
  • 如果您能从 sn-p 中分辨出您的推论是什么,以及您不明白什么,人们会很乐意帮助您。你看到的 sn-p 没有什么大不了的..
  • 不同之处在于第一个示例中您使用原始值,而第二个示例中您使用对象。请看javadude.com/articles/passbyvalue.htm

标签: java arrays pass-by-reference pass-by-value


【解决方案1】:

我会回答你的编辑问题。

public static void main(String[] args) {
    StringHolder[] holders = new StringHolder[]{new StringHolder("string 1")};
    StringHolder tmp = holders[0];
    holders[0].setValue("string 2");
    System.out.println(tmp); // string 2
    System.out.println(holders[0]); // string 2
}

因为两者都持有对同一个对象的引用。


public static void main(String[] args) {
    StringHolder[] holders = new StringHolder[]{new StringHolder("string 1")};
    StringHolder tmp = holders[0];
    holders[0] = new StringHolder("string 2");
    System.out.println(tmp); // string 1
    System.out.println(holders[0]); // string 2
}

在这种情况下,引用由 tmp 持有。在将新的StringHolder 对象分配给holders[0] 后,tmp 中的引用将变为实际对象。 通常,如果您没有tmp,垃圾收集器会删除该对象。 最后你有两个不同的StringHolder对象。

【讨论】:

    【解决方案2】:

    好吧,试着在低层次上解释一下。

    int temp = array[i]; // storing the value in a new variable
    
    array[i] = array[j]; // the value of temp wan't changes because this is a NEW variable and have it's own piece of memory (It's no a reference or pointer like in C)
    
    array[j] = temp; // here the value inside the array is assigned with saved value in temp
    

    【讨论】:

    • 这不是低级。
    • @MuratK。这取决于OP所说的低级意味着什么。从OP的理解水平来看,我相信这已经足够低了:)
    【解决方案3】:

    数组中位置 i 的项目与位置 j 的项目交换。因此,在方法返回后,将在 array[j] 处找到以前称为 array[i] 的项。而之前称为array[j]的项会在方法返回后的array[i]处找到。

    临时变量也用作交换空间。

    【讨论】:

      【解决方案4】:
      int temp = array[i]; // pass by value ??
      

      i位置的元素复制到temp

      array[i] = array[j]; // the value of temp doesn't change, why?
      

      将位置j 的值复制到位置itemp 不会更改,因为它是此语句中未访问的变量。 temp 是一个副本,而不是array[i] 的别名。

      array[j] = temp; // temp == array[i]
      

      将前一行赋值之前在位置i 的值复制到位置jtemp == array[i] 当且仅当 array[i] == array[j] 在方法的开头。

      【讨论】:

        猜你喜欢
        • 2013-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-09
        • 1970-01-01
        • 2012-07-22
        • 1970-01-01
        相关资源
        最近更新 更多