使用Java的@Override注释的最佳实践是什么?为什么?
用@Override注释标记每个被重写的方法似乎有点过分。是否有某些编程情况需要使用@Override,而其他情况不应该使用@Override?
使用Java的@Override注释的最佳实践是什么?为什么?
用@Override注释标记每个被重写的方法似乎有点过分。是否有某些编程情况需要使用@Override,而其他情况不应该使用@Override?
当前回答
最好将它用于打算重写的每个方法,以及Java 6+,用于打算作为接口实现的每个方法。
首先,它会在编译时捕获像“hashcode()”而不是“hashcode()”这样的拼写错误。当真正的原因是您的代码从未被调用时,调试为什么您的方法的结果似乎与您的代码不匹配可能会令人困惑。
同样,如果一个超类改变了一个方法签名,旧签名的重写就会被“孤立”,留下令人困惑的死代码。@Override注释将帮助您识别这些孤儿,以便对它们进行修改以匹配新签名。
其他回答
我认为它在编译时提醒大家,该方法的目的是重写父方法。举个例子:
protected boolean displaySensitiveInformation() {
return false;
}
您将经常看到类似上述方法的内容,它覆盖基类中的方法。这是该类的一个重要实现细节——我们不希望显示敏感信息。
假设这个方法在父类中被更改为
protected boolean displaySensitiveInformation(Context context) {
return true;
}
此更改不会导致任何编译时错误或警告-但它完全改变了子类的预期行为。
回答您的问题:如果在超类中缺少具有相同签名的方法,则表明存在错误,则应该使用@Override注释。
它所做的另一件事是,当读取代码时,它会更明显地改变父类的行为。这有助于调试。
此外,在Joshua Block的著作《Effective Java》(第二版)中,第36项详细介绍了注释的好处。
每次重写一个方法时使用它有两个好处。这样你就可以利用编译器检查来确保你实际上覆盖了一个方法。这样,如果您犯了拼写错误方法名或没有正确匹配参数的常见错误,您将得到警告,您的方法实际上并没有像您认为的那样重写。其次,它使您的代码更容易理解,因为当方法被覆盖时更明显。
此外,在Java 1.6中,您可以使用它来标记方法何时实现接口,以获得同样的好处。我认为最好有一个单独的注释(如@Implements),但总比没有强。
It seems that the wisdom here is changing. Today I installed IntelliJ IDEA 9 and noticed that its "missing @Override inspection" now catches not just implemented abstract methods, but implemented interface methods as well. In my employer's code base and in my own projects, I've long had the habit to only use @Override for the former -- implemented abstract methods. However, rethinking the habit, the merit of using the annotations in both cases becomes clear. Despite being more verbose, it does protect against the fragile base class problem (not as grave as C++-related examples) where the interface method name changes, orphaning the would-be implementing method in a derived class.
当然,这种情况多半是夸张的;派生类将不再编译,现在缺少重命名接口方法的实现,今天可能会使用重命名方法重构操作来处理整个代码库。
鉴于IDEA的检查无法配置为忽略已实现的接口方法,今天我将改变我的习惯和我的团队的代码审查标准。
接口实现上的@Override是不一致的,因为在java中没有“覆盖接口”这样的事情。
@Override on interface implementation is useless since in practise it catches no bugs that the compilation wouldn't catch anyway. There is only one, far fetched scenario where override on implementers actually does something: If you implement an interface, and the interface REMOVES methods, you will be notified on compile time that you should remove the unused implementations. Notice that if the new version of the interface has NEW or CHANGED methods you'll obviously get a compile error anyways as you're not implementing the new stuff.
在1.6中不应该允许接口实现@Override,而不幸的是,eclipse选择自动插入注释作为默认行为,我们得到了大量杂乱的源文件。在阅读1.6代码时,您无法从@Override注释中看出一个方法实际上覆盖了超类中的一个方法,还是仅仅实现了一个接口。
在重写超类中的方法时使用@Override是可以的。