自 JDK5 推出以来, 注解已成为 Java 生态系统不可缺少的一部分. 虽然开发者为 Java 框架 (例如 Spring 的 @Autowired) 开发了无数的自定义注解, 但编译器认可的一些注解非常重要.
在本文中, 极速彩源码搭建 http://bbs.yasewl.com/ 我们将看到 5 个 Java 编译器支持的注解, 并了解其期望用途. 顺便, 我们将探索其创建背后的基本原理, 围绕其用途的一些特质, 以及正确应用的一些例子. 虽然其中有些注解比其他注解更为常见, 但非初学 Java 开发人员都应该消化了解每个注解.
首先, 我们将深入研究 Java 中最常用的注解之一:@Override.
@Override
覆盖方法的实现或为抽象方法提供实现的能力是任何面向对象 (OO) 语言的核心. 由于 Java 是 OO 语言, 具有许多常见的面向对象的抽象机制, 所以在非终极超类定义的非最终方法或接口中的任何方法 (接口方法不能是最终的) 都可以被子类覆盖. 虽然开始时覆盖方法看起来很简单, 但是如果执行不正确, 则可能会引入许多微小的 bug. 例如, 用覆盖类类型的单个参数覆盖 Object#equals 方法就是一种常见的错误:
- public class Foo {
- public boolean equals(Foo foo) {
- // Check if the supplied object is equal to this object
- }
- }
由于所有类都隐式地从 Object 类继承, Foo 类的目的是覆盖 Object#equals 方法, 因此 Foo 可被测试是否与 Java 中的任何其他对象相等. 虽然我们的意图是正确的, 但我们的实现则并非如此. 实际上, 我们的实现根本不覆盖 Object#equals 方法. 相反, 我们提供了方法的重载: 我们不是替换 Object 类提供的 equals 方法的实现, 而是提供第二个方法来专门接受 Foo 对象, 而不是 Object 对象. 我们的错误可以用简单实现来举例说明, 该实现对所有的相等检查都返回 true, 但当提供的对象被视为 Object(Java 将执行的操作, 例如在 Java Collections Framework 即 JCF 中)时, 就永远不会调用它:
- public class Foo {
- public boolean equals(Foo foo) {
- return true;
- }
- }
- Object foo = new Foo();
- Object identicalFoo = new Foo();
- System.out.println(foo.equals(identicalFoo)); // false
这是一个非常微妙但常见的错误, 可以被编译器捕获. 我们的意图是覆盖 Object#equals 方法, 但因为我们指定了一个类型为 Foo 而不是 Object 类型的参数, 所以我们实际上提供了重载的 Object#equals 方法, 而不是覆盖它. 为了捕获这种错误, 我们引入 @Override 注解, 它指示编译器检查覆盖实际有没有执行. 如果没有执行有效的覆盖, 则会抛出错误. 因此, 我们可以更新 Foo 类, 如下所示:
- public class Foo {br/>@Override
- public boolean equals(Foo foo) {
- return true;
- }
- }
如果我们尝试编译这个类, 我们现在收到以下错误: mailto:br/>@Override
- mailto:br/%3E@Override%3Cbr/
- $ javac Foo.java
Foo.java:3: error: method does not override or implement a method from a supertype mailto:br/>@Override
^
1 error
实质上, 我们已经将我们已经覆盖方法的这一隐含的假设转变为由编译器进行的显性验证. 如果我们的意图被错误地实现, 那么 Java 编译器会发出一个错误 -- 不允许我们不正确实现的代码被成功编译. 通常, 如果以下任一条件不满足, 则 Java 编译器将针对使用 @Override 注解的方法发出错误 mailto:br/>@Override
来源: http://www.bubuko.com/infodetail-2669134.html