java - Java 中的多态复制

标签 java reflection polymorphism deep-copy

我突然遇到了在 Java 中进行深度多态复制的问题。实现 Clonable 解决了我的问题,但它通常被称为“坏”技术。

因此,这是我寻找“不可克隆”解决方案的尝试:

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

还有另一种(更短的)方法(使用反射):

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() 来构造一个副本占位符有多“合法”......

上述解决方案是否值得使用,或者是否有更常见/稳健/简单的方法?

谢谢!

最佳答案

对于这个特定用例,我认为您的解决方案没问题。

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

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

有些库支持克隆。看看Kryo .它是一个序列化库,也支持克隆(深克隆和浅克隆),包括没有无参数构造函数或具有最终字段的对象。

关于java - Java 中的多态复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13408202/

相关文章:

swift - Bundle.classNamed(_ 类名 : String) fails but NSClassFromString() work

go - 反射以测试值是否为字符串

java - 为什么这不打印 "super"?

java - native 方法 - java

java - 如何使用 ASM 访问器检查堆栈?

java - 如何从 HTML 中提取字体标签?

Java 反射与抽象类

c - C 中的多态性和赋值运算符

types - Elm中的类型约束

Java:使用多个线程同时在 JPanel 上绘制