我想问一下,两个例子的区别在哪里:
class PassA
{
public static void main(String [] args)
{
PassA p = new PassA();
p.start();
}
void start()
{
long [] a1 = {3,4,5};
long [] a2 = fix(a1);
System.out.print(a1[0] + a1[1] + a1[2] + " ");
System.out.println(a2[0] + a2[1] + a2[2]);
}
long [] fix(long [] a3)
{
a3[1] = 7;
return a3;
}
}
在上面的代码中:
但在下面的代码中
class Test
{
public static void main(String [] args)
{
Test p = new Test();
p.start();
}
void start()
{
boolean b1 = false;
boolean b2 = fix(b1);
System.out.println(b1 + " " + b2);
}
boolean fix(boolean b3)
{
b3 = true;
return b3;
}
}
问题
有什么区别?如何更改代码(示例1)以便{?1}}不会被更改?
答案 0 :(得分:1)
附图
a1 => Long object ID 9999: [3, 4, 5]
a3 => Long object ID 9999: [3, 4, 5] (ie. same object)
然后你做
a3[1] = 7;
我们取消引用a3
并获取
Long object ID 9999: [primitive long value: 3, primitive long value: 4, primitive long value: 5]
然后我们访问索引1处的元素并将其值更改为7
Long object ID 9999: [primitive long value: 3, primitive long value: 7, primitive long value: 5]
在第二种情况下
b1 = primitive boolean value: false
b3 = primitive boolean value: false (no relation to the other, just another false)
然后你做
b3 = true;
此更改仅b3
b3 = primitive boolean value: true (still no relation)
这是因为Java is a pass-by-value language。
要更改第一个代码段,您必须复制数组并在调用方法时传递该副本。
答案 1 :(得分:1)
在Java中,所有内容都按值传递,包括对象引用。在这两种情况下,都会生成参数a3
或b3
的副本。但是,对象引用的副本继续引用同一对象,而基元的副本与原始对象完全断开。
要使第一个示例与第二个示例相同,请在修改之前创建数组的副本(这是一个引用类型对象):
long [] fix(long [] a3)
{
long[] res = Arrays.copyOf(a3, a3.length);
res[1] = 7;
return res;
}
答案 2 :(得分:1)
在Java中,所有内容都按值传递(参见here)。
基本上,有三种变量传递给函数:
对于前两种情况,内容不会改变(例如你的例子2传递一个布尔)
在第三种情况下,内容可以改变(例如你的例子1通过long [] )。
那么,如何不改变示例1中的long []?原始数组是不可能的(除非你在函数内创建另一个数组,使用for循环将输入的所有项复制到这个新数组,然后对这个副本进行操作)。或者在调用函数之前创建初始数组的副本,并使用此副本作为输入调用该函数。
除了将所有内容复制到另一个数组外,不存在不可变的本机原始数组。您需要使用List或其他一些数据结构:您需要使用List或其他一些数据结构(请参阅here)
答案 3 :(得分:0)
Java按值传入,意味着只将原始副本传递给方法。但是,这就是区别:
请参阅下面的经典不良交换示例:
public void badSwap(int var1, int var2)
{
int temp = var1;
var1 = var2;
var2 = temp;
}
这里,它是一个badSwap,因为var1和var2保持不变。只在函数内交换那些整数的副本。
现在,当您的示例中的'al'数组引用复制时,'al'的副本仍然引用原始的{3,4,5}数组。
因此,当您执行以下操作时:
long [] a1 = {3,4,5};
long [] a2 = fix(a1);
a3[1] = 7 in the fix(al) method changes the value of the original al.
而是传入数组本身的副本。
要记住的要点:
引用的副本仍然引用相同的内容,而基本类型(int,boolean ..)的副本与原始文本完全分开。