基本上,下面代码的输出是2.有人可以向我解释为什么会这样吗?非常感谢你:)。
int[][] x = {{3,1,4},{1,5,9}};
int[] y = {2,6,7};
y = x[1];
y[1] = 1;
System.out.println (x[0][1] + x[1][1]);
答案 0 :(得分:1)
您遇到的问题是y和x [1]都引用相同的数组。有关详细信息,请参阅以下评论。
int[][] x = {{3,1,4},{1,5,9}}; // x[0] references an array {3,1,4}; x[1] references an array {1,5,9}
int[] y = {2,6,7}; // You create the array {2,6,7} assigning its reference to y
y = x[1]; // While y was referencing the array {2,6,7} you overwrite this reference by the reference stored at x[1]. This reference is pointing at the array {1,5,9}. So now both y and x[1] are pointing to (or referring to in Java slang) the same array!
y[1] = 1; // So now you are changing the array {1,5,9} to {1,1,9} (y[1] is the same as x[1][1]
System.out.println (x[0][1] + x[1][1]); // x[0][1] (meaning the second value from the first array (referenced by x), which value is 1.) x[1][1] (meaning the second value from the second array, which value is also 1.) So 1 + 1 is in fact 2.
答案 1 :(得分:1)
在开始解释之前,请记住: int是基本类型;数组是一个对象。
看看这个简单的代码:
int[] x = {1,2,3};
int y = x[0];
y = 5;
System.out.print(x[0]);
输出为1
且不 5
,原因如下:
y
被分配 x[0]
的值,基本上是获得它的副本。它并未指向x[0]
,因此对y
的任何未来更改都不适用于x
。
在使用二维数组的情况下,您有以下代码:
int[][] x = {{3,1,4},{1,5,9}};
int[] y = {2,6,7};
y = x[1];
y[1] = 1;
System.out.println (x[0][1] + x[1][1]);
这里的本质区别如下:
y
被分配 x[1]
引用的值,这里也是副本,但因为它是引用(因为x[1]
它是一个数组)它并不重要,导致原始和副本都指向同一个对象。无论您使用y
还是x[1]
,您都指的是同一个对象,即使它们是两个不同的引用。
答案 2 :(得分:1)
因为在java中包含数组的变量(与其他对象一样)只是对这些对象的引用
更多细节:
开始时:
这很容易。
,然后强>
当我们做y = x [1]时,我们不会改变y的值。相反,会发生的是现在指向 x [1]
在内存中,我们有一个数组{1,5,9}和两个变量在那里(x [1]和y)。这也意味着在内存中,我们仍然有一个数组{2,6,7},但没有变量正在查看(指向)它(因为y改变为查看与x [1]相同的位置)。在java中,垃圾收集器会自动查找不再使用的内存位置并清理内存
最后
更改x [0]或y将访问内存中的相同位置,因此两个变量的值都将更改。做
y[1] = 1;
与执行
完全相同x[1][1] = 1;
这样做时,我们更改数组,它变为{1,1,9}
所以x[0][1] + x[1][1]
等于1+1
这将在您编程时始终出现,因为这对所有对象都是相同的行为。
旁注在谈到Java中的引用时,您会看到许多人在确切的术语上争论。 Java不像c ++那样通过引用传递。你开始记得的是变量在分配给数组或对象时的行为方式
答案 3 :(得分:1)
我们的起始位置是
y
可以显示为
x → { [0] , [1] } ↓ ↓ // each 1D array like {3,1,4} can be also shown as {3,1,4} {1,5,9} // { [0] [1] [2] } // ↓ ↓ ↓ y → {2,6,7} // 3 1 4 but I skipped that for simplicity
(因为Java中的任何2D数组都只是其他1D数组的1D数组)。
当我们执行x[1]
y
时,现在将引用存储在x[1]
中的 相同数组 (它不是具有相同元素的原始数组的副本,它是相同的数组)。
所以情况弓类似于
x → { [0] , [1] } ↓ ↓ {3,1,4} {1,5,9} ↑ y ──────────────────────┘
这意味着我们可以通过两个引用y[1] = 1;
和x[1]
更改同一个数组,并且每个更改也可以通过其他引用查看。
所以如果我们这样做
x
它也会影响{{3,1,4},{1,1,9}};
所持的数组,如
x → { [0] , [1] } ↓ ↓ {3,1,4} {1,1,9} ↑ └─changed y ─────────────────────┘
现在x[0][1] = 1
看起来像x[1][1]=1
。
x → { ├[0] → { │ ├─[0] → 3 │ ├─[1] → 1 //x[0][1] │ └─[2] → 4 │ } └[1] → { ├─[0] → 1 ├─[1] → 1 //x[1][1] └─[2] → 9 } }
因此,2
和__rtruediv__
的总和为__truediv__
。
答案 4 :(得分:1)
这就是为什么:
int[][] x = {{3,1,4},{1,5,9}};
int[] y = {2,6,7};
y = x[1]; //{1, 5, 9}
y[1] = 1; //{1, 1, 9}
System.out.println (x[0][1]/* {3,*1*,4} */ + x[1][1] /* {1, *1*, 9} */);
在 Java 中,当您分配像这些y = x[1];
这样的数组或以任何可能的方式传递数组时(例如,方法),您实际传递了{{1}的副本} reference
数组到另一个数组,数组x[1]
具有与y
到x
相同的引用,其中数组exsis和更改值GC
y[1]
您实际更改的值是在y[1] = 1; //{1, 1, 9}
和y[1]