4

图像您有一个如下所示的类:

class Foo
{
   public String x;
   public int y;
   public long l;
}

然后我们在某个地方:

Foo foo1 = new Foo();
foo1.x = "a";
foo1.y = 3;
foo1.l = 2L;

然后在其他地方我们有另一个 Foo 对象,其字段尚未初始化。

Foo foo2 = new Foo();
//foo2 = foo1; 

鉴于将变量 foo1 表示的对象的引用分配给变量 foo2 不是我在这里想要做的,因为我想保留对 foo2 表示的对象的引用,那么复制 foo1 的状态的最简单方法是什么到 foo2?

换句话说,我如何自动执行此操作?

foo2.x = foo1.x;
foo2.y = foo1.y;
foo2.l = foo1.l;
4

6 回答 6

3

如果 Foo 是一个 JavaBean,如果它有适当的 setter / getter 而不是公共字段,你可以使用 Apache CommonsBeanutils.copyProperties(Object dest, Object orig)

于 2013-06-11T15:25:01.600 回答
2

Java中没有MOVE CORRESPONDING。您需要将其完整地写出来(或“其他一些技巧”)。

该代码不是 Java 的惯用代码。那里有公共领域。处理这种情况的更好方法可能是使用不可变的Foo. 然后,您可能会拥有一个具有Foo可变引用的对象。

于 2013-06-11T15:23:55.610 回答
1

创建一个复制构造函数

class Foo
{
   public String x;
   public int y;
   public long l;

   public Foo(Foo foo){
       this.x = foo.x;
       this.y = foo.y;
       this.l = foo.l;
   }
}

现在你可以像这样使用它

Foo foo1 = new Foo();
foo1.x = "a";
foo1.y = 3;
foo1.l = 2L;

Foo foo2 = new Foo(foo1);

您也可以通过实施克隆方法来做到这一点。但我认为创建复制构造函数是更好更简单的方法。检查有效java的这个链接

于 2013-06-11T15:21:55.510 回答
0

您可以实现一个复制构造函数,例如

public Foo (Foo foo) {
   this.x = foo.getX();
   this.y = foo.getY();
   this.z = foo.getZ();
}

然后创建一个新的Fooas

Foo foo2 = new Foo(foo1);


或者,您可以让您的Foo 实现 Cloneable并定义clone()

public Foo clone() {
    return new Foo(this.x, this.y, this.z);
}

然后使用clone()as创建一个副本

Foo foo2 = foo1.clone();

注意您可能会跳过定义clone()(此处),因为默认情况下Object.clone()实现会进行浅拷贝,并且可以使用您在此处拥有的简单字段。

于 2013-06-11T15:22:20.393 回答
0

除了Cloneable接口和复制构造函数之外,还有另一种解决方案:冻结/解冻模式

这是一种模式,它允许您从一个对象中获取一个构建器,该对象的所有状态都是预先填充的,如果需要,可以对其进行修改,然后再次冻结它。如果你实现它,你可以这样做:

final Foo foo2 = foo.thaw().freeze();

好处是所有实例Foo都是不可变的:不再有设置器!修改:

final Foo foo2 = foo.thaw().setY(something).freeze();

这是没有任何缺点的 JavaBeans,并且具有构建器模式的启动能力。

于 2013-06-11T15:23:01.483 回答
0

您可以让 Foo 实现Cloneable接口并覆盖方法clone。在方法的主体中,您初始化一个新的 Foo 并将这个 Foo 的字段的值分配给新的 Foo。

于 2013-06-11T15:23:52.047 回答