示例是具有swap()方法的Card类。两个Card对象被实例化。该方法通过声明第三个Card变量来交换它们,但不实例化第三个对象。第三个变量用作支持交换的临时持有人。我希望交换不会起作用,因为temp变量引用第一个对象,然后将第一个对象分配给第二个对象,并且将第二个对象分配给temp,根据我的假设,该对象将对第一个对象进行更改
public class Tester
{
public static void main(String[] args)
{
Card[] cards = new Card[2];
cards[0] = new Card('x');
cards[1] = new Card('y');
System.out.println( cards[0].getVal() + "\n" + cards[1].getVal() + "\n" );
Card.swap(cards);
System.out.println( cards[0].getVal() + "\n" + cards[1].getVal() + "\n" );
}
}
//Card class --------------------------------------------------------------------
class Card
{
private char value;
public Card(char value)
{
set(value);
}
public static void swap(Card[] cards){
Card temp = cards[0];
cards[0] = cards[1];
cards[1] = temp;
}
public boolean set(char value)
{
this.value = value;
return true;
}
public char getVal()
{
return value;
}
}
输出:
x
y
y
x
我希望在将温度分配给卡[1]之前,卡[0]和卡[1]会引用卡[1]所引用的内存。我希望取消对卡片[0]的取消引用。
实际结果是卡[0]与卡[1]交换了。 (这是一个真实的副本,还是一个引用开关?)我的理解是,由于所有Java变量都是引用,因此,当cards [0]的取消引用成为cards [1]时,temp的取消引用将成为cards [1]。现在看来,即使没有在“ new”操作中为其分配堆对象,temp仍具有自己的内存。我在其他地方读过一些东西,向我暗示这是方法变量的工作方式,但是我找不到任何可以证实用户定义类型或任何非原始类型的方法变量是如何工作的东西。
答案 0 :(得分:1)
Card temp = cards[0];
cards[0] = cards[1];
cards[1] = temp;
“卡X”对象(由数组的0位置保持)的引用已分配给“临时”变量。
然后将“卡片Y”对象(由数组的1位置保存)的引用分配给数组的0位置。
然后将“卡X”对象(由“ temp”变量保存)的引用分配给数组的1个位置。
稍后,当取消引用数组在其0位置上保持的引用时,将按预期方式获得“卡片Y”。
答案 1 :(得分:1)
Java上下文中的引用与C或C ++中的引用不同。在Java中,您宁愿处理指针,而这些指针是按值传递。
因此,也没有自动复制对象(假定的对象),并且在交换之后,仍然只有两个events.result
对象,与调用该方法之前创建的对象相同。
问题Is Java “pass-by-reference” or “pass-by-value”?的答案和评论可能有助于理解这一点。