Java “深度复制”;“对象”;类型

Java “深度复制”;“对象”;类型,java,deep-copy,Java,Deep Copy,我有一个对象,其成员类型为“object”: 是否可以深度复制MyObject?实现Cloneable标记接口,您可以通过克隆复制MyObject class MyObject implements Cloneable { public Object clone(){ try { return super.clone(); } catch (CloneNotSupportedException e) { return null

我有一个对象,其成员类型为“object”:


是否可以深度复制
MyObject

实现
Cloneable
标记接口,您可以通过克隆复制
MyObject

class MyObject implements Cloneable {
    public Object clone(){
      try {
        return super.clone();
      } catch (CloneNotSupportedException e) {
           return null; 
      }
   }
}
成员还需要是
可克隆的
,否则它将抛出
CloneNotSupportedException


尽管它是一个bean,因此不是不变的,但我还有一个选择:

如果您为您的对象实现它(这要求您使用生成器类),那么您可以执行以下操作:

final MyObject copy = orig.thaw().freeze();
我发现它比
Cloneable
甚至构建器(这是一个可逆的构建器)更方便,并且经常使用这种模式

作为奖励,您可以使您的对象不是bean,因此是不可变的。我个人对豆子有一种深深的厌恶,这就是为什么我会想到这个

这种模式也是递归的。假设您有类
Out
In
,其中
In
Out
的成员。让我们说,中的
服从冻结/解冻。您的
Out
代码将变为:

public final class Out
    implements Frozen<Builder>
{
    private final In in;

    private Out(final Builder builder)
    {
        in = builder.in.freeze();
    }

    public static newBuilder()
    {
        return new Builder();
    }

    public In getIn()
    {
        return in;
    }

    @Override
    public Builder thaw()
    {
        return new Builder(this);
    }

    public static final class Builder
        implements Thawed<Out>
    {
        private In.Builder in;

        private Builder()
        {
        }

        private Builder(final Out out)
        {
            in = out.in.thaw();
        }

        public Builder setIn(final In in)
        {
            this.in = in.thaw();
        }

        @Override
        public Out freeze()
        {
            return new Out(this);
        }
    }
}
公开期末考试出局
冻结的器具
{
私人决赛;
私人建筑(最终建筑商)
{
in=builder.in.freeze();
}
公共静态newBuilder()
{
返回新的生成器();
}
getIn()中的public
{
返回;
}
@凌驾
公共建筑商解冻()
{
返回新的构建器(此);
}
公共静态最终类生成器
解冻的器具
{
私人住宅,建筑商住宅;
私人建筑商()
{
}
私人建筑商(最终输出)
{
in=out.in.thaw();
}
公共建筑商设置(最终设置)
{
this.in=in.thaw();
}
@凌驾
公众假期冻结
{
归还新的(本);
}
}
}

最终的结果是调用
copy=orig.saw().frezze()
会返回一个与
的新实例相同的副本。在当前的实现中,这是不可能的,因为
成员可以是任何东西,而您无法复制您不知道的东西。

可克隆的
;)+1太快和尖锐:)如果
成员
不能
克隆怎么办。。。clone()真的是深度复制吗,我认为除非重写,否则它只是一个字段一个字段地复制…?必须:+1,这是正确的答案。+1根本无法保证对象是可复制的,无论是深度复制还是浅度复制,直到运行时,它唯一保证的接口是Object。我认为使用
反射
@ronnk可以复制一些对象(性能相当糟糕),但不是全部。我想到了数据库/网络连接和打开的文件。@JoachimIsaksson Ok:-)您不能保证在这里进行深度复制,因为对象可以是任何东西。例如,如果不是所有对象成员都实现Serializable,则此处的序列化技术将失败。
final MyObject copy = orig.thaw().freeze();
public final class Out
    implements Frozen<Builder>
{
    private final In in;

    private Out(final Builder builder)
    {
        in = builder.in.freeze();
    }

    public static newBuilder()
    {
        return new Builder();
    }

    public In getIn()
    {
        return in;
    }

    @Override
    public Builder thaw()
    {
        return new Builder(this);
    }

    public static final class Builder
        implements Thawed<Out>
    {
        private In.Builder in;

        private Builder()
        {
        }

        private Builder(final Out out)
        {
            in = out.in.thaw();
        }

        public Builder setIn(final In in)
        {
            this.in = in.thaw();
        }

        @Override
        public Out freeze()
        {
            return new Out(this);
        }
    }
}