如果您可以自由使用扩展而不是实现,那么您可以这样做:
public interface Thing { ... }
public abstract class Copyable {
public final Copyable copy() {
Copyable clone = createCopy();
if (clone.getClass() != getClass())
throw new RuntimeException("Copy has wrong type!");
return clone;
}
protected abstract Copyable createCopy();
}
然后像这样使用它:
public class Test extends Copyable implements Thing {
public String content = null;
@Override
public Copyable createCopy() {
Test clone = new Test();
clone.content = this.content;
return clone;
}
}
/*code somewhere*/ {
Test t1 = new Test();
t1.content = "Hello world!";
Test t2 = (Test)t1.copy();
System.out.println(t2.content);
}
这样做的一个问题是,这Copyable
不是一个接口。但是,正如示例中所见,这可以毫不费力地使用,但是在语言级别上不支持使用的类检查。换句话说,createCopy
抽象方法并不局限于它所复制的类,而这一切都取决于扩展类的程序员Copyable
或扩展它的类。
积极的一面是,如果您.copy()
在对象上调用 ,它必须返回一个与自身相同的对象。null
如果需要,您可以 return 代替异常。然后你得到了好或没有。
但是,老实说,我真的不明白,为什么你的createCopy
本地方法有一个参数。它可能是一个静态方法......虽然我什至无法想象该代码块会包含什么:
static <X extends Thing> X copy(X object) { ... }
愿你可以将实践与静态泛型方法结合起来,结果会变得更友好一点:
public interface Thing extends Cloneable {
public static <X extends Thing> X copy(X thing) {
Object clone = thing.clone();
if (clone.getClass() != getClass())
throw new RuntimeException("Copy has wrong type!");
return (X)clone;
}
}
public class ThingA implements Thing {
public Object clone() { ... }
}
/*code somewhere*/ {
ThingA a1 = new ThingA();
ThingA a2 = Thing.copy(a1);
}
尽管如此,克隆方法仍受例外而不是语言限制的约束,但我认为这是最好的解决方案。