为什么数组的输出给出b的修改值;
public static void main(String[] args)
{
int i=0;
int a[] = {1,2,3,4};
int b[] = {5,6,7,8};
a=b;
b[2] = 9;
while(i<4)
{
System.out.println(a[i]);
i++;
}
}
答案 0 :(得分:3)
因为 a 和 b 具有相同的引用。与基本数据相同。
答案 1 :(得分:2)
写入a=b;
时,a
和b
指向同一数组,即{5,6,7,8};
。
然后通过a
或b
更新它都没关系,它将对同一数组进行更改。
答案 2 :(得分:0)
在Java中,字节数组是一种特殊的对象类型。在这种情况下,您将使用类型为I[
的整数数组。在Java中,对象实例始终是引用而不是按值保存。您可以很好地看到将它们打印出来会发生什么情况:
int[] a = { 1, 2, 3, 4 };
int[] b = { 5, 6, 7, 8 };
System.out.printf("Before: a=%s b=%s%n", a, b);
a = b;
System.out.printf("After: a=%s b=%s%n", a, b);
b[2] = 9;
System.out.println(Arrays.toString(a));
将打印出
Before: a=[I@15db9742 b=[I@6d06d69c
After: a=[I@6d06d69c b=[I@6d06d69c
[5, 6, 9, 8]
如您所见,它打印出的引用类型为I[
,然后是@
,然后是 reference 。首先,引用指向两个不同的对象实例,但是在a = b
之后,a
和b
都引用了首先分配给b
的对象实例。这意味着a
和b
的任何更改都将在同一对象上。当然,无论打印出a
还是b
的值都没关系。
如果要确保在更改a
时不会更改b
,则需要克隆对象。数组实现Cloneable
接口时支持克隆:
int[] a = { 1, 2, 3, 4 };
int[] b = { 5, 6, 7, 8 };
System.out.printf("Before: a=%s b=%s%n", a, b);
a = b.clone();
System.out.printf("After: a=%s b=%s%n", a, b);
b[2] = 9;
System.out.println(Arrays.toString(a));
将打印出
Before: a=[I@15db9742 b=[I@6d06d69c
After: a=[I@7852e922 b=[I@6d06d69c
[5, 6, 7, 8]
如您所见,a
现在指向一个全新的数组实例,其原始值首先由b
引用。
请注意,打印对象引用适用于数组,因为数组不实现toString
,当期望String
时会自动调用它。在这种情况下,它将使用Object#toString
来打印引用,如下所示。
如果实现了toString
,则无法打印出对对象实例的引用。相反,您可以使用System.identityHashCode(variable)
来指示引用是否相等。或者,您可以简单地使用if (a == b)
来测试引用相等性。
答案 3 :(得分:-1)
在进行数组声明时,只有大括号中的内容才实际存储在内存中。 (实际上,存储了更多的信息,但是对于您的问题范围,您可以假装它只是花括号中的内容)
您的变量'a'和'b'只是指向内存中指向花括号中值位置的引用。
所以当你说 a = b 现在,您的数组引用“ a”不再指向带有存储值的原始位置,而是指向也由“ b”指向的位置和存储值。
答案 4 :(得分:-1)
a = b
这是一个浅表副本,因为a和b具有相同的引用,所以对数组“ a”的任何更改都会对数组“ b”的更改
如果要复制值(深层复制)
for(int i = 0 ; i<a.length() , i++) // assume the size of two array are equal
{
b[i] = a[i] ;
}