Java中的多态复制

2024-01-02

我突然遇到了一个用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(),是:

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

有一些库支持克隆。看一眼Kryo http://code.google.com/p/kryo/。它是一个序列化库,还支持克隆(深克隆和浅克隆),包括没有无参数构造函数或具有最终字段的对象。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java中的多态复制 的相关文章

随机推荐

  • 防止iOS接近传感器使屏幕变黑

    我已经看到这个问题被问了几次 但没有人回答它 事实上这可能是不可能的 但我想知道是否有一种方法可以防止 iPhone 上的邻近状态发生变化时屏幕变黑 我已经实现了一种方法 可以在接近状态发生变化时执行某些操作 但屏幕会闪烁为黑色 我想避免这
  • Visual Studio 2013 中的自定义脚手架模板

    以前 使用 Visual Studio 2012 我能够将CodeTemplates文件夹到我的项目目录然后修改现有的T4 templates或者添加全新的 T4 模板来满足我特定的代码生成要求 前面描述的方法似乎不再适用于 Visual
  • numpy apply_along_axis 一维数组

    当 numpy apply along axis 采用一维数组作为输入时会发生什么 当我在一维数组上使用它时 我看到一些奇怪的东西 y array 1 2 3 4 第一次尝试 apply along axis lambda x x gt 2
  • AngularJs - RXJS 可观察取消订阅

    我已经设置了 RXJS 可观察的 我有两个组件订阅服务工厂中的一个主题 如何取消订阅选定组件的主题 以便按下按钮即可停止收听主题广播 看我的jsfiddle取消订阅应用程序 https jsfiddle net bkarv 0maek0qr
  • stdcall 可以有可变参数吗?

    据我所知 只有 caller clean stack 约定可以使用变量参数 顺便说一句 WinApi StringCchPrintfW 是这样声明的 我删除了 SAL 内联 HRESULT stdcall字符串CchPrintfW STRS
  • WidgetKit(意图)-如何链接从远程获取的多个动态意图?

    我正在为我的应用程序创建一个小部件 并使用从 API 获得的动态数据成功添加意图配置 此代码片段获取列表并将其返回到 Intent func provideLeagueOptionsCollection for intent LeagueC
  • 我可以注释“fun”声明的完整类型吗?

    在学习环境中 我可以选择哪些选项来为函数提供类型签名 标准 ML 没有像 Haskell 那样的顶级类型签名 以下是我考虑过的替代方案 模块签名 需要单独的签名文件 或者在与模块本身相同的文件内的单独块中定义的类型签名 这需要使用模块 在任
  • jquery 没有父级的子选择器

    我正在查看创建轮播菜单的教程中的一些代码 并注意到没有父项的父子选择器 以前从未见过这个 并且对它实际在做什么感到困惑 参见下面的代码 var wrapper gt div this css overflow hidden slider w
  • 生成最近两周的日期范围?

    我想生成 2 个 DATETIME 代表从星期日到星期六 2x 的最近两周 它不应该包括当前不完整的一周 感谢你的帮助 一些可以工作的东西 利用美妙的DateTime课程
  • Flutter上如何用pop获取返回值?

    我想知道如何在 Flutter 上使用 pop 获取两个值 我尝试编写代码 但我得到了异常 必须向文本小部件提供非空字符串 这是代码 第一屏 ElevatedButton child const Text move to second sc
  • Powershell 将数据传输到外部控制台应用程序

    我有一个可以接受标准输入的控制台应用程序 它缓冲数据直到执行命令 此时它会执行所有数据 并将输出发送到标准输出 目前 我正在从 Powershell 运行该应用程序 将命令通过管道传输到其中 然后解析输出 传入的数据相对较小 然而 该应用程
  • MySQL 中嵌套循环中的多个游标

    我想做一些在 MySQL 中显得有点复杂的事情 事实上 我希望打开一个游标 执行一个循环 并在这个循环中 使用上一个要执行的提取中的数据打开第二个游标 并重新循环结果 DECLARE idind INT DECLARE idcrit INT
  • 如何确定 Signal R 正在使用哪种传输方法

    我正在使用 signal r 服务器和 Web 客户端编写一个测试应用程序 我想知道是否有办法确定或让服务器知道客户端正在与服务器建立哪种传输方法 对于在客户端和服务器之间具有持久双向连接的 websockets 或持续轮询服务器直到服务器
  • 创建具有过滤范围的单元格内下拉列表

    我正在使用谷歌电子表格 为了说明我的问题 我使用范围A2 A8用于数据验证D2 and E2 但因为在细胞内D2 你应该只选择一种动物 我想用以下内容过滤范围B2 B8 我尝试过的是使用我自己的公式 FILTER A2 A8 IS B2 B
  • 当模板类型是基本类型时通过引用传递的成本

    我一直听说确保最佳性能的良好做法是 通过基本类型 int double 按价值 通过常量引用传递类 如今 使用 C 11 并在编译器下进行全面优化 当通过 const 引用传递基本类型时是否会产生开销 而且 当T is int将实现以下功能
  • 如何防止收到的短信到达收件箱?

    我正在开发一个简单的应用程序 它接收但不处理短信 它检查每条传入的短信是否有特定的关键词 如果短信包含该关键字 那么它会做出相应的响应 如果关键字不存在 那么我的应用程序什么也不做 我有这么多工作 我想知道是否有一种方法可以阻止手机上的默认
  • 鼠标移出时关闭 AJAX 控制工具包 BallonPopupExtender

    有人知道如何从客户端关闭 Ballon Popup Extender 吗 一切都很好 但由于我将 BPE 设置为在鼠标悬停时显示 所以它在鼠标移出时没有任何关闭或隐藏方法 这确实不切实际 我尝试过 function hideElement
  • 为什么要刷新由其他逻辑处理器引起的内存顺序冲突的管道?

    The vTune 文档中描述了 Memory Order Machine Clear 性能事件 https software intel com en us vtune amplifier help mo machine clear ov
  • Flex 到 HTML5 - 表示层(canvas、div、???)

    我的问题是关于从 Flex3 迁移到 HTML5 的问题 我实际上想迁移自己而不是应用程序 问题是 什么方向是最好的 和Flex知识最相似的 也许我会重新实现我的 Flex 库中已有的一些自定义组件 我认为我必须在 HTML5 中自己实现一
  • Java中的多态复制

    我突然遇到了一个用Java进行深度多态复制的问题 实施Clonable解决了我的问题 但它通常被称为 坏 技术 因此 我尝试寻找 不可克隆 的解决方案 public class Parent int x public Parent publ