为什么没有一种简单的方法来复制Java中的对象?

时间:2011-08-11 11:45:02

标签: java inheritance object reference copy

我的GUI中有一个类TimeLine。我有一个函数,我想复制这个TimeLine并修改其中的数据,而不会影响我的GUI中的TImeLine。

我搜索了一些论坛,并没有找到一个简单的方法,因为Java让参考文章坚持下去。为什么没有一种简单的方法来创建一个没有引用前一个对象的新对象(TimeLine)?

请帮我复制一下这个TimeLine对象!

5 个答案:

答案 0 :(得分:4)

此处其他作者建议的clone()方法和Cloneable接口是使用错误的假设创建的,即使用通用复制方法是个好主意。默认实现执行当前对象的浅层克隆,但您可以覆盖它以执行深度克隆。

没有正确的通用方法来复制任意对象,您要复制的内容取决于所涉及的对象。例如,不可变对象永远不需要复制(这只是浪费空间),而某些类型的对象无法被复制(如何复制FileOutputStream,例?)。

我发现最优雅的方式是不可变对象,其方法返回只有一个字段更改的副本:

class Pony {
    private final String name;
    private final Color color;
    private final int tailLength;

    // constructors and accessors omitted

    Pony withName(String newName) {
        return new Pony(newName, color, tailLength);
    }

    Pony withColor(Color newColor) {
        return new Pony(name, newColor, tailLength);
    }

    Pony withTailLength(String newTailLength) {
        return new Pony(name, color, newTailLength);
    }
}

// Usage:

Pony tony = new Pony("Tony", Color.DAPPLE, 32);
Pony maurice = tony.withName("Maurice") // Maurice is like Tony, but black.
                   .withColor(Color.BLACK);

不幸的是,你通过这种方式得到了很多样板,并且也没有主流的IDE支持(尽管可能有插件)。与此相关的是Josh Bloch在Effective Java中推荐的Builder pattern

答案 1 :(得分:3)

您可能需要考虑为您的班级编写复制构造函数而不是clone()

public TimeLine(TimeLine original) {
    this.foo = original.foo;
    this.bar = original.bar;
}

复制班级中任何参考字段的值时要小心。确保您需要浅拷贝还是深拷贝。

答案 2 :(得分:2)

在使用运算符“=”的Java中,您只需复制对象的引用。如果要按值实现复制,请使用克隆操作(类Object的clone()方法)或实现自己的克隆方法(覆盖已实现的方法)。

请注意,如果您的类将其他对象存储在其中,则最终也应克隆这些对象(DEEP COPY)。

答案 3 :(得分:1)

如果要使用clone()

复制对象

如果我误解了你的问题,请发表评论

答案 4 :(得分:1)

您正在寻找clone方法。 (我已经来回询问要引用哪些文档,即维基百科,它的处理方式更加彻底。Java doc当然更正式。

例如

MyObject a = new MyObject();
a.setSomething( 2 );
MyObject b = a.clone();

// now b.getSomething().equals(a.getSomething()) (maybe == too, depends on class)
// and b.equals(a)
// b != a