我今天遇到了Eclipse编译器的一个奇怪的行为,我不知道该怎么想。我们正在尝试创建一个有用的Cloneable
界面:
public interface PublicCloneable extends Cloneable {
Object clone();
static <T extends PublicCloneable> T clone(final T obj) {
if (obj != null) {
return (T) obj.clone();
}
return null;
}
}
有趣的是,编译器抱怨obj.clone()
:Unhandled exception type CloneNotSupportedException
我知道如何修复它,我们可以将obj
投射到PublicCloneable
并完成它。但是我感兴趣的是:为什么编译器更喜欢Object
的方法来实现一种方法呢?
答案 0 :(得分:0)
从这个回答:https://stackoverflow.com/a/13776045/896588
[...]虽然接口本身不扩展Object,但已知任何实现都会。
因此,由于您有一个接口,声明的clone()
不会覆盖clone()
的{{1}}。在这一点上,它正式是一个新宣布的行动。
尝试实现您的界面。您将看到它强制您从Object
覆盖clone()
但没有例外,因为它还必须完成界面。
你在这里创造了一个棘手而复杂的情况。编译器知道您的实现类还将扩展Object
并继承Object
,但异常。当它在类型层次结构中查找声明时,它首先找到一个并停止搜索。它不再关心clone()
(毫无例外地会有PublicCloneable
)也属于层次结构。如果您将参数类型直接更改为clone()
,那就是它开始搜索的位置并找到另一个。
这可能解释得过于简化,但我似乎无法在JLS中找到相应的正式部分。