以下代码编译时没有错误:
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
必须有public
clone()
方法-但是你从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();
。