如何将一个(JavaBean)对象的状态复制到另一个已存在的对象中?

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;

你并没有失去对foo2的引用,只是在设置属性。 - nachokk
这几乎是“克隆”对象的相反操作。其思想不是得到一个全新的对象,它镜像另一个对象的状态。而是用另一个对象的状态重新初始化现有对象。 - J Smith
似乎没有多少人在阅读这个问题中的“现有”一词。 - Tom Hawtin - tackline
6个回答

3

如果Foo是一个JavaBean,也就是说如果它有适当的setter/getter而不是公共字段,那么您可以使用Apache Commons Beanutils.copyProperties(Object dest, Object orig)


可能就是我正在寻找的。我会去检查一下。谢谢。 - J Smith

2

Java 中没有 MOVE CORRESPONDING。您需要完整地编写它(或者使用“其他一些技巧”)。

这段代码不符合Java的惯用法,其中有公共字段。也许更好的处理方式是使用不可变的 Foo,但未描述具体情况。然后您可以有一个对 Foo 的引用的可变对象。


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);

您也可以通过实现clone方法来实现此操作。但我认为创建复制构造函数是更好、更容易的方式。请查看effective java的链接。


哈哈..我们的答案看起来像是使用复制构造函数创建的 :P - vidit

0

你可以实现一个像拷贝构造函数这样的函数

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

然后创建一个新的Foo的副本,如下:

Foo foo2 = new Foo(foo1);


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

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

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

Foo foo2 = foo1.clone();

请注意,您可以跳过在此处定义clone(),因为默认情况下Object.clone()实现执行浅复制,并且它可以与您这里的简单字段一起使用。

0
除了Cloneable接口和复制构造函数之外,还有另一种解决方案:freeze/thaw pattern
这是一种模式,它允许您从一个对象中获取一个构建器,并预填充该对象的所有状态,如果需要,可以进行修改,然后再次冻结。如果您实现了它,您可以执行以下操作:
final Foo foo2 = foo.thaw().freeze();

额外加分的是,所有的Foo实例都是不可变的:不再有setter了!要进行修改:

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

这是JavaBeans,没有任何缺点,并且还具有生成器模式的强大功能。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接