Java:传递“this”的副本? [复制]
Posted
技术标签:
【中文标题】Java:传递“this”的副本? [复制]【英文标题】:Java: pass in copy of "this"? [duplicate] 【发布时间】:2012-01-18 21:32:43 【问题描述】:可能重复:How do I copy an object in Java?
我的类Claus
中有一个函数,它调用一个函数来接受类型Claus
。我目前正在传递this
作为参数,但是它正在编辑我不希望它做的类的当前实例。相反,我希望它克隆类的当前实例并对其进行编辑,保持副本分开。我该怎么做?
编辑
也许我应该进一步澄清我的问题......
我有一个在另一个对象内的对象.. 例如Claus
和floss
。我一直在阅读shallow copy
和deep copy
,我认为我的Claus
复制正确。我就是这么干的……
public Claus(Claus g)
cla = new Floss(g.getFloss());
//irrelevant other variables...
p = g.getP();
c = g.getC();
但是,Claus
中的函数我在构造函数中声明的方式完全相同.. 就是....
cla = new Floss(g.getFloss());
其中 cla = Floss
变量和 g = Claus
正在传递给构造函数。 Floss
对象似乎并没有像它应该那样创建深层副本。为什么会这样?
【问题讨论】:
你能提供代码来说明你在做什么吗? Dose Claus 实现 Cloneable?如果你传入一个克隆怎么办?您的描述本身并没有难闻的代码气味,但可能有一种非常轻微的气味。我想知道你是不是搞错了。也许你最好告诉我们你想要实现什么行为,而不是你如何在代码中尝试实现它。 伙计,这里就像是克隆人的攻击。 我提供了有关我的问题的更新以帮助澄清问题。 “Floss 对象似乎没有像它应该的那样创建深层副本。”您能否提供更多详细信息,您有什么证据表明它没有正确地制作深拷贝? 【参考方案1】:实现Cloneable
并使用this.clone()
,就像任何其他变量一样。
【讨论】:
【参考方案2】:你应该看看 Object#clone 方法
http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#clone%28%29
【讨论】:
+1 教我一些东西 :)【参考方案3】:考虑为您的班级实施copy constructor。这是一个构造函数,它接受另一个相同类型的实例并将其状态复制到新对象中。
【讨论】:
【参考方案4】:void foo(Claus c)
不是foo(this)
,而是foo(new Claus(this))
编辑:
然后像这样在Claus中定义一个拷贝构造函数:
public Claus(Claus c)
this.whatever = c.whatever;
// etc.
【讨论】:
我不认为Claus的构造函数会是这个样子。 在 Java 中复制构造函数? Java 中的这种风格很糟糕吗?抱歉,我有 C++ 背景,但很想了解 Java 标准。 Java 中没有内置的复制构造函数 内置啊。我不知道这一点,并补充说他应该定义自己的。谢谢你的提示!定义自己的复制 ctor 而不是使用克隆是否被认为是不好的风格?【参考方案5】: Object objClone = obj.clone();
克隆将返回,就像听起来一样,是您的对象的克隆。 Clone() 是 Object 超类的一个方法,所以如果你实现了 Cloneable 接口,你所有的对象都可以访问这个方法。
【讨论】:
仅当obj
的类型实现Cloneable
时才有效。否则你会得到CloneNotSupportedException
。【参考方案6】:
你可以这样做:
public class MyObject
//attributes
private String attr1;
public MyObject() //first construct
public MyObject(MyObject obj)
//do copy of all attributes
this.attr1 = obj.getAttr1();
//setters and getters
public void method(MyObject obj)
MyObject obj2 = new MyObject(obj);
//your processing
然后调用它
MyObject obj = new MyObject();
obj.setAttr1("someone");
obj.method(obj);
希望对您有所帮助..
【讨论】:
【参考方案7】:您可能想要实现.clone()
方法。但是,您必须确保它实现了Cloneable
接口。
但建议首选其他方法,例如 Copy Constructor 和 static-factory-method,它们将对象作为参数并创建一个新实例,该实例是传递对象。
但是,您真正需要注意的一件事是,只是所有字段的浅副本就足够了,还是需要深副本。因为,如果您需要深拷贝并创建对象的浅拷贝,则可能意味着代码中存在潜在的错误。
【讨论】:
【参考方案8】:正如其他人所说,您应该实现clone()
方法或创建一个复制构造函数。
无论您选择哪种解决方案,您都需要制作所谓的“深拷贝”。如果对象很简单,那么创建深层副本就很简单。如果对象很复杂,一个技巧是序列化和反序列化对象。这将以最少的工作量进行深层复制。
每当我这样做时,我都喜欢使用XStream 而不是本机Java 序列化。它将对象序列化为 XML,包括任何嵌套的对象和集合,然后您可以对其进行反序列化以获得深层副本。以下代码很可能适用于您的课程,无需修改:
public Claus clone(Claus source)
XStream xstream = new XStream();
String serializedObj = xstream.toXML(source);
return (Claus) xstream.fromXML(serializedObj);
【讨论】:
以上是关于Java:传递“this”的副本? [复制]的主要内容,如果未能解决你的问题,请参考以下文章