如何使默认' clone() '在一个接口?



以下代码编译时没有错误:

public interface ICloneable {
default ICloneable clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
public static void main(String[] args) {
var object = new ICloneable() {
};

System.out.println("ok");
}
}

但是在运行时它说:

ICloneable.java:9: error: clone() in Object cannot implement clone() in ICloneable
var object = new ICloneable() {
^
attempting to assign weaker access privileges; was public

有可能克服吗?

以下代码编译时没有错误

不,它没有。

你看到的错误实际上是一个编译错误。

为什么会出现这个错误

我不确定您是否理解clone()本身是java.lang.Object已经具有的方法:

接口never中的default实现覆盖在类的实际类层次结构中找到的任何实现。意思是,IClonable接口中的clone()默认实现是永远不会使用-因为所有类在其层次结构中都有Object,其clone()优先。

然而,IClonable必须有publicclone()方法-但是你从j.l.Object"免费"获得的clone()protected,因此你的代码不会在这里编译。

有可能克服吗?

确定。

最好的:不要叫它clone()

如果clone()已经被j.l.Object占用了,找另一个词。当然,除非你的意图是使用一个接口来强制一个默认的impl强制它public,在这种情况下…

使用抽象类代替

如果ICloneable是一个抽象类,你就不会得到这个错误。

…否则

不,这是无法修复的。没有办法告诉javac使用接口的默认impl,即使impl存在于类层次结构中。

注意:不鼓励使用IClonable样式命名。强烈不鼓励使用java中半熟的clone()功能(Object自己的clone()是该功能的一部分)。尽可能使用不可变类型。如果不可能,想想克隆可能意味着什么,并为它制定一个方法。"你可以克隆我"的一般原则作为一个概念被打破了。例如,克隆一个不可变类型是没有意义的,然而,将不可变类型的clone()方法写成public Object clone() { return this; }是有误导性的。作为一个概念,它是不可挽救的。这是有原因的,例如arraylist有new ArrayList<T>(otherArraylist)作为克隆的建议方法,而不是List<T> clone = otherArrayList.clone();

最新更新