代码之家  ›  专栏  ›  技术社区  ›  daydreamer

关于Java cloneable

  •  89
  • daydreamer  · 技术社区  · 14 年前

    我在找一些关于Java的教程 Cloneable

    我想知道以下情况:

    1. 可克隆的 意味着我们可以通过 实施 可克隆的 这样做的缺点?
    2. 如果对象是
    6 回复  |  直到 7 年前
        1
  •  156
  •   isapir    7 年前

    你应该知道的第一件事 Cloneable

    很难用 是的,付出的努力是不值得的。

    SerializationUtils (深层克隆)或 BeanUtils (浅层克隆),或者只使用复制构造函数。

    See here 可克隆的 ,这解释了该方法的许多缺点。( Joshua Bloch 曾是Sun的员工,领导了众多Java功能的开发。)

        2
  •  39
  •   Luke Hutteman    14 年前

    不幸的是,Cloneable本身只是一个标记接口,即:它没有定义clone()方法。

    即使这是您正在寻找的行为,您仍然需要实现自己的clone()方法才能将其公开。

    在实现您自己的clone()时,我们的想法是从super.clone()创建的对象开始,该对象保证是正确的类,然后在浅层副本不是您想要的情况下进行任何额外的字段填充。从clone()调用构造函数可能会有问题,因为如果子类希望添加自己的附加可克隆逻辑,则这将中断继承;如果调用super.clone(),则在这种情况下将获取错误类的对象。

    这种方法绕过了可能在构造函数中定义的任何逻辑,这可能是有问题的。

    出于这些原因,大多数开发人员不使用Cloneable,而只是实现一个复制构造函数。

    有关Cloneable的更多信息和潜在缺陷,我强烈推荐Joshua Bloch的《有效Java》一书

        3
  •  12
  •   karobar    9 年前
    1. 克隆要求您以某种方式处理CloneNotSupportedException,或者麻烦客户机代码处理它。
    2. 好处很小-您不必手动编写复制构造函数。

    所以,明智地使用Cloneable。与你为做好每一件事而付出的努力相比,它并没有给你足够的好处。

        4
  •  7
  •   Charles    11 年前

    克隆是一种基本的编程模式。事实上,Java在很多方面可能实现得很差,但这丝毫没有减少克隆的必要性。而且,很容易实现克隆,无论你希望它如何工作,浅层的,深层的,混合的,无论什么。如果愿意的话,甚至可以为函数使用clone名称,而不实现Cloneable。

    假设我有类A、B和C,其中B和C是从A派生的。如果我有一个A类型的对象列表,如下所示:

    ArrayList<A> list1;
    

    ArrayList<A> list2 = new ArrayList<A>();
    for(A a : list1) {
        list2.add(new A(a));
    }
    

    如果对象实际上是B或C类型的,则不会得到正确的副本。如果A是抽象的呢?现在,有人提出:

    ArrayList<A> list2 = new ArrayList<A>();
    for(A a : list1) {
        if(a instanceof A) {
            list2.add(new A(a));
        } else if(a instanceof B) {
            list2.add(new B(a));
        } else if(a instanceof C) {
            list2.add(new C(a));
        }
    }
    

    你想做的是:

    ArrayList<A> list2 = new ArrayList<A>();
    for(A a : list1) {
        list2.add(a.clone());
    }
    

    很多人都指出了克隆的基本Java实现存在问题的原因。但是,这样很容易克服:

    public A clone() {
        return new A(this);
    }
    

    B类:

    @Override
    public B clone() {
        return new B(this);
    }
    

    C类:

    @Override
    public C clone() {
        return new C(this):
    }
    

        5
  •  5
  •   ILMTitan    14 年前

    A) 与复制构造函数相比,克隆并没有很多优点。最大的可能是创建完全相同动态类型的新对象的能力(假设声明的类型是可克隆的并且具有公共克隆方法)。

    B) 默认克隆创建浅复制,除非克隆实现更改了浅复制,否则它将保持浅复制。这可能很难,特别是如果你的班级有期末考试的字段

    波佐是对的,克隆人可能很难得到正确的答案。复制构造函数/工厂将满足大多数需求。

        6
  •  0
  •   027    9 年前

    Cloneable的缺点是什么?

    如果要复制的对象具有组合,则克隆非常危险。在这种情况下,您需要考虑以下可能的副作用,因为克隆会创建浅复制:

    假设您有一个对象来处理与数据库相关的操作。比如说,那个物体 Connection 对象作为属性之一。

    所以当有人创造了 originalObject cloneObject . 原始对象 景物 保持相同的参考 反对。

    原始对象 关闭 连接 景物 不会起作用,因为 connection 原始对象 .

    如果要克隆具有IOStream属性的对象,则可能会出现类似的问题。

    如果对象是复合对象,递归克隆是如何发生的?

    Cloneable执行浅拷贝。意思是原始对象和克隆对象的数据将指向相同的引用/内存。