出于某种原因,当我从现有实例创建对象的新实例并更改新实例中的值时,它还会更改现有实例中的值。我希望它只是改变了新实例中值的状态。我不确定为什么会这样。
Foo existing = new Foo(1, "foo");
for (int i = 0; i < 10; i++) {
Foo newFoo = existing;
System.out.println(newFoo.getName()); //Prints "foo" as expected
newFoo.setName("bar");
System.out.println(existing.getName()); //This prints out "bar"?
}
这两个对象都不是静态的。
答案 0 :(得分:6)
您可以在运行时使用以下命令创建新实例:
Foo newFoo = existing.getClass().newInstance();
请注意,新创建的实例不会是 existing
的副本。
但是,如果您需要以获得existing
对象的副本,则可以使用Clonable
界面进行一些操作。
首先,您必须使Foo
类实现Clonable
接口:
public class Foo implements Clonable { ... }
然后,您需要提供clone()
方法的实现,该方法将返回您对象的副本:
public Foo clone() {
return new Foo(this.id, this.name); //for example
}
最后,您可以触发新引入的clone()
方法,如下所示:
Foo newFoo = existing.clone();
这会为您提供一个新的Foo
对象,但会使用existing
中的复制属性。
答案 1 :(得分:1)
请注意,当你这样做时
Foo newFoo = existing;
您没有创建新实例。相反,您只需将newFoo
变量指向同一个对象existing
指向。
你所做的基本上是这样的:
Foo existing = new Foo(1, "foo") <=> existing -> Foo(1, "foo")
Foo newFoo = existing <=> existing -> Foo(1, "foo") <- newFoo
newFoo.setName("bar") <=> existing -> Foo(1, "bar") <- newFoo
System.out.println(existing.getName()) <=> System.out.println(Foo(1, "bar").getName())
如果您想创建一个新实例,您可以这样做:
Foo newFoo = new Foo(existing.getId(), existing.getName());
答案 2 :(得分:0)
您正在创建新引用,而不是新实例。尝试这样的事情......
Foo newFoo = oldFoo.clone()
这保留了原始对象&#39;值
答案 3 :(得分:0)
要创建Foo
实例的副本,您可以从Cloneable
继承并实施clone()
方法,如下所示:
class Foo implements Cloneable {
@Override
public Foo clone() {
try {
return (Foo)super.clone();
}
catch(CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
}
(另见http://docs.oracle.com/javase/8/docs/api/java/lang/Cloneable.html)
答案 4 :(得分:0)
创建一个复制构造函数:
public Foo (Foo another) {
this.propertyA = another.propertyA;
// etc.
}
然后,在for
循环中:
Foo existing = new Foo(1, "foo");
for (int i = 0; i < 10; i++) {
Foo newFoo = new Foo(existing);
// system out etc
}
这是复制类实例的最佳方法。
答案 5 :(得分:0)
你不创建一个新实例,你只是创建一个指向同一个实例的新变量。你要么必须创建一个复制构造函数,要么创建一个具有现有值的新实例实例如下所示:
Foo instance = new Foo(existing.getPropertyA(), existing.getPropertyB());
答案 6 :(得分:-1)
在第
行Foo newFoo = existing;
您没有创建Foo的新实例;您正在将existing
的引用复制到变量newFoo
中对existing
或newFoo
采取的任何操作都会影响相同的基础对象
有关如何在java中复制对象的非常详尽的讨论:How do I copy an object in Java?