Java 注解是用于我们程序源代码的元数据(关于数据的描述)。
它们为编译器提供了关于程序的额外信息,但不是程序本身的一部分。这些注解不会影响编译程序的执行。
注解以 @
开头。其语法是
@AnnotationName
让我们来看一个 @Override
注解的例子。
@Override
注解指定了带有此注解的方法覆盖了具有相同方法名、返回类型和参数列表的超类方法。
在覆盖方法时,使用 @Override
不是强制性的。但是,如果我们使用它,当覆盖方法时出现任何错误(例如参数类型错误),编译器会给出错误。
示例 1: @Override 注解示例
class Animal {
public void displayInfo() {
System.out.println("I am an animal.");
}
}
class Dog extends Animal {
@Override
public void displayInfo() {
System.out.println("I am a dog.");
}
}
class Main {
public static void main(String[] args) {
Dog d1 = new Dog();
d1.displayInfo();
}
}
输出
I am a dog.
在此示例中,方法 displayInfo()
同时存在于超类 Animal 和子类 Dog 中。当调用此方法时,将调用子类的方法而不是超类中的方法。
注解格式
注解还可以包含元素(成员/属性/参数)。
1. 标记注解 (Marker Annotations)
标记注解不包含成员/元素。它仅用于标记声明。
其语法为
@AnnotationName()
由于这些注解不包含元素,可以省略括号。例如,
@Override
2. 单元素注解 (Single element Annotations)
单元素注解只包含一个元素。
其语法为
@AnnotationName(elementName = "elementValue")
如果只有一个元素,约定俗成将其命名为 value。
@AnnotationName(value = "elementValue")
在这种情况下,也可以省略元素名称。元素名称默认为 value。
@AnnotationName("elementValue")
3. 多元素注解 (Multiple element Annotations)
这些注解包含多个由逗号分隔的元素。
其语法为
@AnnotationName(element1 = "value1", element2 = "value2")
注解放置
通过将注解放置在任何声明的上方,都可以用注解标记它。从 Java 8 开始,注解也可以放在类型的前面。
1. 在声明上方
如上所述,Java 注解可以放置在 类、方法、接口、字段和其他程序元素声明的上方。
示例 2: @SuppressWarnings 注解示例
import java.util.*;
class Main {
@SuppressWarnings("unchecked")
static void wordsList() {
ArrayList wordList = new ArrayList<>();
// This causes an unchecked warning
wordList.add("programiz");
System.out.println("Word list => " + wordList);
}
public static void main(String args[]) {
wordsList();
}
}
输出
Word list => [programiz]
如果在不使用 @SuppressWarnings("unchecked")
注解的情况下编译上述程序,编译器仍会编译该程序,但会给出类似以下的警告:
Main.java uses unchecked or unsafe operations. Word list => [programiz]
我们收到警告
Main.java uses unchecked or unsafe operations
是由于以下语句。
ArrayList wordList = new ArrayList<>();
这是因为我们没有定义 ArrayList 的泛型类型。我们可以通过在尖括号 <>
中指定泛型来修复此警告。
ArrayList<String> wordList = new ArrayList<>();
2. 类型注解 (Type annotations)
在 Java 8 之前,注解只能应用于声明。现在,也可以使用类型注解。这意味着我们可以在使用类型的任何地方放置注解。
构造函数调用
new @Readonly ArrayList<>()
类型定义
@NonNull String str;
此声明指定类型为 String
的非空变量 str,以避免 NullPointerException
。
@NonNull List<String> newList;
此声明指定类型为 String
的非空列表。
List<@NonNull String> newList;
此声明指定类型为 String
的非空值列表。
类型转换
newStr = (@NonNull String) str;
extends 和 implements 子句
class Warning extends @Localized Message
throws 子句
public String readMethod() throws @Localized IOException
类型注解能够更好地分析 Java 代码并提供更强的类型检查。
注解类型
1. 预定义注解
@Deprecated
@Override
@SuppressWarnings
@SafeVarargs
@FunctionalInterface
2. 元注解
@Retention
@Documented
@Target
@Inherited
@Repeatable
3. 自定义注解
这些注解类型在 Java 注解类型 教程中有详细描述。
注解的用途
- 编译器指令 - 注解可用于向编译器发出指令、检测错误或抑制警告。内置注解
@Deprecated
、@Override
、@SuppressWarnings
用于这些目的。 - 编译时指令 - 这些注解提供的编译时指令有助于软件构建工具生成代码、XML 文件以及更多内容。
- 运行时指令 - 一些注解可以定义为在运行时向程序发出指令。这些注解通过 Java Reflection 访问。