我们应该在接口的方法实现中使用 @Override 吗?

488

实现接口方法的方法是否应该使用@Override进行注释?

Override注释的javadoc文档说:

表示方法声明旨在覆盖超类中的方法声明。 如果一个方法被注释为此注释类型,但没有覆盖超类方法,则编译器需要生成错误消息。

我认为接口从技术上讲不是超类,或者它是吗?

问题阐述


1
我找不到 @Override 文章的替代品(Oracle 最近移动了旧的 Sun 博客)。你知道该怎么找到它吗? - Bill the Lizard
4
到了现在(2015年),我们应该已经有了一个@Implement(s)注释。这将使事情更清晰明了! - Alex
3
到目前为止(2015年),我们应该在Java 8中使用 @Override 吗? - Lorenzo Sciuto
15个回答

341

每次有机会时,你应该使用@Override。这可以防止犯下简单的错误。例如:

class C {
    @Override
    public boolean equals(SomeClass obj){
        // code ...
    }
}

这段代码无法编译,因为它没有正确覆盖public boolean equals(Object obj)方法。

实现接口的方法(仅限1.6及以上版本)或覆盖超类方法的方法也是如此。


152
请注意,在Java 5中,无法为实现接口的方法添加@Override注释 - 这会导致错误。但在Java 6中则允许这样做。 - Bill Michell
18
不,实际上不是这样的。事实上,在Eclipse中用接口填充方法时,它会自动插入@ Override。 - jjnguy
14
直到回答中包含有关Java 1.5到1.6在实现接口方法方面行为差异的提及为止。因为我见过它让人们感到困惑,它确实值得一提。 - Grundlefleck
1
+1 表示在 1.5 版本之后。我花了大约 20 分钟才弄清楚为什么 Eclipse 给我报错,但是通过这个问题,我意识到我的新项目正在使用 Java 1.5。 - grinch
2
如果Eclipse出现问题,请将您的JDK升级到> 1.5,并将编译器兼容级别更改为1.6或1.7。要执行此操作,请右键单击您的项目->属性->Java编译器,然后选择高于1.5的选项。 - Rose
显示剩余7条评论

118

我认为javac的行为已经改变了 - 在1.5中,它禁止了注解,但在1.6中则不是。该注解提供了一个额外的编译时检查,因此如果您正在使用1.6,我建议您使用它。


19
@Michael,您可以注意到是否删除了任何界面。 - Sanghyun Lee

83
如果可用,应始终使用@Override来注释方法。在JDK 5中,这意味着覆盖超类的方法,在JDK 6和7中,它意味着覆盖超类的方法和实现接口的方法。原因如前所述,是它允许编译器捕获您认为正在覆盖(或实现)方法,但实际上正在定义新方法(不同的签名)的错误。 equals(Object)equals(YourObject)示例是一个标准案例,但对于接口实现也可以提出同样的论点。
我想象的原因是,实现接口方法没有强制注释是因为JDK 5将其标记为编译错误。如果JDK 6使该注释强制性,它将破坏向后兼容性。
我不是Eclipse用户,但在其他IDE(IntelliJ)中,在项目设置为JDK 6+项目时,只有在实现接口方法时才添加@Override注释。我想Eclipse是类似的。
然而,我更希望看到不同的注释用于此用途,也许是@Implements注释。

17

12

JDK 5.0不允许您在实现接口中声明的方法上使用@Override注释(这会导致编译错误),但JDK 6.0允许。因此,您可以根据需要配置项目首选项。


7
阅读Java8中的javadoc,您可以在接口Override的声明中找到以下内容:
如果一个方法被注解为此注解类型,则编译器需要生成错误消息,除非至少满足以下条件之一:
1.该方法覆盖或实现了在超类型中声明的方法。
2.该方法具有与任何在{@linkplain Object}中声明的公共方法相等的重写签名。
因此,至少在Java8中,您应该在接口方法的实现上使用@ Override。

6

如果一个具体类没有覆盖抽象方法,使用 @Override 来实现是一个开放性问题,因为编译器会不可避免地警告您有任何未实现的方法。在这些情况下,可以认为它会影响可读性--它是你代码中需要阅读的更多内容,稍微有点叫做 @Override 而不是 @Implement


3
如果实现接口的类是一个抽象类,@Override 有助于确保实现的是一个接口方法;如果没有 @Override,即使实现方法的签名与接口中声明的方法不匹配,抽象类也可以编译通过;不匹配的接口方法仍然未被实现。这是@Zhao引用的Java文档。
引用块中提到的“该方法覆盖或实现了在超类型中声明的方法”明显是指抽象超类;接口不能被称为超类型。
因此,在具体类中,对于接口方法的实现,@Override 是多余且无意义的。

这已经是多余的了。在STS4中,当一个类方法实现接口方法并被@ Override修饰时,编译器错误消息会显示“...必须覆盖超类方法”。 - Park JongBum

3

这不是JDK的问题。在Eclipse Helios中,它允许对实现接口方法使用@ Override注释,无论是JDK 5还是6。至于Eclipse Galileo,无论是JDK 5还是6,都不允许使用@ Override注释。


3

重写你自己类中继承的方法通常不会在使用IDE进行重构时出现问题。但是,如果你重写了从库中继承的方法,建议仍然使用它。如果不这样做,你经常会在稍后库更改时得到没有错误,但是隐藏得很好的错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接