从现有实例创建新实例

时间:2015-03-29 19:46:40

标签: java

出于某种原因,当我从现有实例创建对象的新实例并更改新实例中的值时,它还会更改现有实例中的值。我希望它只是改变了新实例中值的状态。我不确定为什么会这样。

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"?
}

这两个对象都不是静态的。

7 个答案:

答案 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中对existingnewFoo采取的任何操作都会影响相同的基础对象

有关如何在java中复制对象的非常详尽的讨论:How do I copy an object in Java?