# Java 注解

> 原文： [https://www.programiz.com/java-programming/annotations](https://www.programiz.com/java-programming/annotations)

#### 在本教程中，我们将通过示例学习什么是注解，不同的 Java 注解以及如何使用它们。

Java 注解是程序源代码的元数据（有关数据的数据）。

它们向编译器提供有关程序的其他信息，但不属于程序本身。 这些注解不影响编译程序的执行。

注解以`@`开头。 其语法为：

```java
@AnnotationName

```

* * *

让我们以`@Override`注解为例。

`@Override`注解指定已用此注解标记的方法覆盖具有相同方法名称，返回类型和参数列表的超类方法。

覆盖方法时，并非必须使用`@Override`。 但是，如果使用它，则在覆盖该方法时，如果出现错误（例如错误的参数类型），则编译器将给出错误。

### 示例 1：`@Override`注解示例

```java
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();
  }
} 
```

**输出**

```java
I am a dog. 
```

在此示例中，方法`displayInfo()`同时存在于超类`Animal`和子类`Dog`中。 调用此方法时，将调用子类的方法，而不是超类中的方法。

* * *

## 注解格式

注解也可以包括元素（成员/属性/参数）。

### 1.标记注解

标记注解不包含成员/元素。 它仅用于标记声明。

其语法为：

```java
@AnnotationName()

```

由于这些注解不包含元素，因此可以排除括号。 例如，

```java
@Override

```

* * *

### 2.单元素注解

单个元素注解仅包含一个元素。

它的语法是：

```java
@AnnotationName(elementName = "elementValue")

```

如果只有一个元素，则习惯上将该元素命名为`value`。

```java
@AnnotationName(value = "elementValue")

```

在这种情况下，也可以排除元素名称。 元素名称默认为`value`。

```java
@AnnotationName("elementValue")

```

* * *

### 3.多元素注解

这些注解包含多个用逗号分隔的元素。

它的语法是：

```java
@AnnotationName(element1 = "value1", element2 = "value2")

```

* * *

## 注解位置

通过将任何声明置于该声明之上，可以将其标记为带有注解。 从 Java 8 开始，注解也可以放在类型之前。

### 1.上方的声明

如上所述，Java 注解可以放在类，方法，接口，字段和其他程序元素声明的上方。

### 示例 2：`@SuppressWarnings`注解示例

```java
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();
  }
} 
```

**输出**：

```java
Word list => [programiz] 
```

如果上述程序在不使用`@SuppressWarnings("unchecked")`注解的情况下进行编译，则编译器仍将编译该程序，但会给出如下警告：

```java
Main.java uses unchecked or unsafe operations.
Word list => [programiz] 
```

我们收到警告

```java
Main.java uses unchecked or unsafe operations

```

由于以下语句。

```java
ArrayList wordList = new ArrayList<>(); 
```

这是因为我们尚未定义`ArrayList`的通用类型。 我们可以通过在尖括号`<>`中指定泛型来解决此警告。

```java
ArrayList<String> wordList = new ArrayList<>();

```

* * *

### 2.类型注解

在 Java 8 之前，注解只能应用于声明。 现在，也可以使用类型注解。 这意味着我们可以在使用类型的任何地方放置注解。

**构造器调用**

```java
new @Readonly ArrayList<>() 
```

**类型定义**

```java
@NonNull String str;

```

该声明指定类型为`String`的非空变量`str`以避免`NullPointerException`。

```java
@NonNull List<String> newList;

```

该声明指定类型为`String`的非空列表。

```java
List<@NonNull String> newList; 
```

该声明指定类型为`String`的非空值的列表。

**类型转换**

```java
newStr = (@NonNull String) str; 
```

`extends`或`implements`子句

```java
class Warning extends @Localized Message

```

**`throws`子句**

```java
public String readMethod() throws @Localized IOException

```

类型注解使 Java 代码可以得到更好的分析，并提供更强大的类型检查。

* * *

## 注解类型

1\. **预定义的注解**

1.  `@Deprecated`
2.  `@Override`
3.  `@SuppressWarnings`
4.  `@SafeVarargs`
5.  `@FunctionalInterface`

2\. **元注解**

1.  `@Retention`
2.  `@Documented`
3.  `@Target`
4.  `@Inherited`
5.  `@Repeatable`

3\. **自定义注解**

这些注解类型在 [Java 注解类型](/java-programming/annotation-types "Java Annotation Types")教程中有详细描述。

* * *

## 注解的使用

*   **编译器指令**-注解可用于向编译器提供指令，检测错误或禁止警告。 内置注解`@Deprecated`，`@Override`和`@SuppressWarnings`用于这些目的。
*   **编译时指令**-这些注解提供的编译时指令可帮助软件构建工具生成代码，XML 文件等。
*   **运行时指令**-可以定义一些注解以在运行时向程序提供指令。 这些注解是使用 Java 反射访问的。