Java Stack保存推送元素的副本而不是对它们的引用

时间:2012-11-29 19:38:22

标签: java stack

Stack<Animal> myStack = new Stack<Animal>();
Animal a = new Animal();
a.setValueOfAnimal(5);
myStack.push(a);
a.setValueOfAnimal(15);
System.out.println(myStack.pop().getValueOfAnimal());

上面你看到了一个主要方法示例。

输出结果为:15。

无论如何都要使堆栈中的对象安全吗?当我修改“Animal a”的值时,我不希望修改堆栈中的对象。

这是否受任何内置Java类的支持?

4 个答案:

答案 0 :(得分:4)

  

我不希望在修改时修改堆栈中的对象   “动物a”的价值。

然后你必须创建Animal的新实例。

Animal中添加Stack引用时,您只需存储引用的副本,该副本指向相同的Animal。因此,如果您使用原始引用修改Animal实例,则也会修改Stack中的引用。

所以,你需要修改你的代码: -

myStack.push(a);
a = new Animal(); // Make the reference `a` point to a new instance.
a.setValueOfAnimal(15);

答案 1 :(得分:3)

您不能,除非您在a = new Animal()之后添加myStack.push(a);

您还可以提供复制构造函数:

public Animal(Animal someAnimal) {
    this.value = someAnimal.value;
}

然后你可以写:

myStack.push(new Animal(a)); //put a copy in the stack

答案 2 :(得分:2)

推送后

Nulling 引用会使堆栈上的对象安全:

Animal a = new Animal();
a.setValueOfAnimal(5);
myStack.push(a);
a = null;  // remark here.

答案 3 :(得分:0)

您的代码可视化流程如下图所示:

enter image description here

提示:
Java parameters passing is “pass-by-value”,如果是对象值,该值将是引用地址。

为什么会出现意外问题:
在调用 Animal a 方法后更新方法参数 myStack.push(a); 数据。

如果您不需要这种行为:

  • 要么在调用 myStack.push(a); 方法后取消引用指针。
    a = null;
  • 或者你可以使用相同的引用名称a在内存中创建一个新对象
    a = new Animal();