在代码中更容易解释所以
Object anObj;
anObj = new MyObj();
anObj = new Rectangle();
anObj.clone();//this doesnt exist because its on the root Object class
在这个例子中我可以使用什么代替Object.clone()方法?
-----------------------额外信息---------------------- --------
我已经添加了额外的信息,但它似乎已经在所有答案的中间,所以在这里它又是如此,它可以被阅读。
大家都非常有帮助克隆或复制这个主题,我现在需要考虑一下。但他们对最初的问题没有帮助。也许更多来自我的信息将帮助您了解后续的内容。
我正在覆盖每个对象的克隆,并添加完全克隆对象所需的所有其他克隆和复制方法,这包括添加自定义方法来复制bufferedimage。 即: -
public Object clone() {//i copied from 'thelost's answer
try {
CloningExample copy = (CloningExample)super.clone();
copy.names = (LinkedList)names.clone();
return copy;
} catch (CloneNotSupportedException e) {
return null;
}
}
但是我的类中有一个变量是Object,但是因为它包含不同类型的各种其他对象,我的每个类型都会有一个克隆方法,但是不能检查我的每个类型是否然后调用clone ()我的类型,这将是非常长的,因为我有很多类型,我无法看到如何轻松地复制或克隆对象。我有没有办法写一个像这样的静态方法?
static findTypeAndCopy(Object thisobj){
if(thisobj==null)
return null;
if(thisobj instanceOf MyObj1){
return ((MyObj1)thisobj).clone();
}else if(thisobj instanceOf MyObj2){
return ((MyObj2)thisobj).clone();
...
etc
}
???
答案 0 :(得分:4)
最好的办法是避免克隆,如it is broken.
Cloneable
接口没有方法clone
。方法clone
在protected
类中定义为Object
。因此,要调用clone
,您需要知道有权访问clone
的对象类型。
更好的想法是复制构造函数(如Bloch推荐)或序列化和反序列化(例如通过XML)
也许你可以通过反思访问clone
,但我不确定。我劝阻它。
答案 1 :(得分:4)
您似乎已经意识到Java中的Cloneable
已被破坏。
以下是 Effective Java 2nd Edition 的作者an interview with Josh Bloch的一些引用:
如果您已经阅读了我的书中有关克隆的内容,特别是如果您在这些内容之间进行了阅读,您会发现我认为
clone
已经被彻底打破了。存在一些设计缺陷,其中最大的缺点是Cloneable
接口没有clone
方法。这意味着它根本不起作用:制作一些Cloneable
并没有说明你可以用它做什么。相反,它说明了内部可以做些什么。它表示如果反复调用super.clone
,最终会调用Object
的{{1}}方法,此方法将返回原始字段的字段副本。但它没有说明你可以用一个实现
clone
接口的对象做什么,这意味着你不能进行多态Cloneable
操作。
以下是本书的一些引用,第11项:明智地覆盖clone
:
[...]您最好提供替代的对象复制方法,或者根本不提供该功能。
[...]对象复制的一个很好的方法是提供复制构造函数或复制工厂。复制构造函数只是一个构造函数,它接受一个参数,其类型是包含构造函数的类:
clone
复制工厂是复制构造函数的
public Yum(Yum yum);
工厂模拟:static
public static Yum newInstance(Yum yum);
2.0 如果你真的坚持使用Cloneable
这样的功能没有被打破,你可以写下这样的东西(为额外的爵士乐做好准备):
Cloneable
输出应该是这样的(as seen on ideone.com):
public class DupableExample {
interface Dupable<T> {
T dup();
}
static class Sheep implements Dupable<Sheep> {
Sheep(Sheep sheep) { }
@Override public Sheep dup() {
return new Sheep(this);
}
}
public static void main(String[] args) {
Dupable<?> dupable = new Sheep(null);
System.out.println(dupable);
System.out.println(dupable.dup());
// no cast needed
Sheep dolly2 = new Sheep(null).dup();
}
}
现在给予任何DupableExample$Sheep@{some hexadecimal code}
DupableExample$Sheep@{a different hexadecimal code, in all likelyhood}
,您可以在其上调用Dupable<T>
以获得您期望的副本。
这只是一个概念验证:在实际实现中,您的复制构造函数/复制工厂/任何复制机制实际上都会实现复制逻辑,而T dup()
将是Dupable<T>
顶部-level public
。
答案 2 :(得分:0)
您无法确定某个类是否具有克隆能力,因为clone()
是来自Object的方法。您可以做的最好的事情是检查班级是否为Cloneable。通常当一个类为Cloneable时,这意味着开发人员覆盖了clone()
方法。
但即便如此,Object
也无法调用此方法。
有反射解决方案。但正如医生所说:
即使反射调用clone方法,也不能保证它会成功。
答案 3 :(得分:-1)
您可以检查它是否实现了Cloneable
接口,如果是,则使用克隆方法。
here就是如何自己实现它的例子。
答案 4 :(得分:-1)
正如其他人所说:Clonable被破坏了,您应该考虑其他选项,例如复制构造函数。话虽如此,如果你真的必须使用clone(),这里有一个解决方案:
Object clone = null;
if(anObj instanceof Clonable) {
Method cloneMethod = anObj.getClass().getMethod("clone");
/*
* TODO: Handle the case where an object is cloneable but
* does not have a public clone() method.
*/
clone = cloneMethod.invoke(anObj);
} else {
throw new RuntimeException("can't clone object");
}
或者你可以使用反射来按字段克隆对象,如果它没有实现clone()...获取所有字段,将值复制到新对象。但是如果对象没有no-arg构造函数,这很棘手。
答案 5 :(得分:-1)
interface PublicCloneable extends Cloneable{
public Object clone();
}
class MyObject implements PublicCloneable {
public Object clone() {
return super.clone();
}
}
class MainObject {
public static void main(String[] params) {
Object m = new MyObject();
if (m instanceof PublicCloneable) {
Object c = m.clone();
}
}
}