Java中的多态副本

Java中的多态副本

本文介绍了Java中的多态副本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我突然遇到了在Java中制作深度多态副本的问题.实施 Clonable 可以解决我的问题,但通常被称为不良"技术.

I've suddenly encountered a problem of making a deep polymorphic copy in Java. Implementing Clonable solves the problem in my case, but it is often referred as a "bad" technique.

因此,这是我寻找无克隆"解决方案的尝试:

So, here are my attempts to find a "no-Clonable" solution:

public class Parent {
    int x;

    public Parent() {}

    public Parent(int x0) {
        x = x0;
    }

    public Parent copy() {
        Parent b = new Parent();
        b.assign(this);

        return b;
    }

    protected void assign(Parent c) {
        x = c.x;
    }

    @Override
    public String toString() {
        return getClass().getName() + ", " + x;
    }
}

public class Child extends Parent {
    int y;

    protected Child() {}

    public Child(int x0, int y0) {
        super(x0);
        y = y0;
    }

    @Override
    public Child copy() {
        Child b = new Child();
        b.assign(this);

        return b;
    }

    @Override
    protected void assign(Child c) {
        super.assign(c);
        y = c.y;
    }

    @Override
    public String toString() {
        return getClass().getName() + ", " + x + "," + y;
    }
}

public class Test {
    public static void main(String[] args) {
        Parent x = new Parent(5);
        Child y = new Child(10, 20);
        Parent z = x.copy();
        Parent w = y.copy();

        System.out.println(x);
        System.out.println(y);
        System.out.println(z);
        System.out.println(w);
    }
}

输出为:

com.xxx.zzz.Parent, 5
com.xxx.zzz.Child, 10,20
com.xxx.zzz.Parent, 5
com.xxx.zzz.Child, 10,20

另一种(更短的)相同方法(使用反射):

And another(shorter) way of doing the same (using Reflection):

public class Parent {
    int x;

    public Parent() {}

    public Parent(int x0) {
        x = x0;
    }

    public Parent copy() {
        try {
            Parent b = getClass().newInstance();
            b.assign(this);
            return b;
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
    }

    protected void assign(Parent c) {
        x = c.x;
    }

    @Override
    public String toString() {
        return getClass().getName() + ", " + x;
    }
}

public class Child extends Parent {
    int y;

    protected Child() {}

    public Child(int x0, int y0) {
        super(x0);
        y = y0;
    }

    protected void assign(Child c) {
        super.assign(c);
        y = c.y;
    }

    @Override
    public String toString() {
        return getClass().getName() + ", " + x + "," + y;
    }
}

无需在Child类中重写copy().但是我不确定使用getClass().newInstance()构造副本占位符有多合法"……

No need for overriding copy() in the Child class. But i'm not sure how 'legal' it is to use getClass().newInstance() to construct a copy placeholder...

以上解决方案值得使用还是有更多常见/健壮/简单的方法?

Are the solutions above worth using or there are more common/robust/simple approaches ?

谢谢!

推荐答案

对于这种特殊用例,您的解决方案对我来说还可以.

Your solution looks okay to me, for this particular use case.

使用newInstance()的主要限制是:

  • 仅适用于具有无参数构造函数的对象,并且
  • 它将无法克隆具有最终字段的对象

有些库支持克隆.看看 Kryo .它是一个序列化库,还支持克隆(深层和浅层),包括不带no-arg构造函数或具有最终字段的对象.

There are some libraries which support cloning. Take a look at Kryo. It is a serialization library which also supports cloning (deep and shallow), including of objects without no-arg constructors or which have final fields.

这篇关于Java中的多态副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 13:46