Java 注释类型
Java 注释类型
在本教程中,我们将通过示例了解不同类型的 Java 注解。
Java 注释是我们程序源代码的元数据(关于数据的数据)。 Java SE 提供了几个预定义的注解。此外,我们还可以根据需要创建自定义注解。
如果您不知道注解是什么,请访问 Java 注解教程。
这些注解可以分类为:
1. 预定义注释
@Deprecated
@Override
@SuppressWarnings
@SafeVarargs
@FunctionalInterface
2. 自定义注解
3. 元注释
@Retention
@Documented
@Target
@Inherited
@Repeatable
预定义注释类型
1。 @已弃用
@Deprecated
annotation 是一个标记注解,指示元素(类、方法、字段等)已被弃用并已被更新的元素替换。
它的语法是:
@Deprecated
accessModifier returnType deprecatedMethodName() { ... }
当程序使用已被声明为 deprecated 的元素时,编译器会生成警告。
我们使用 Javadoc @deprecated
用于记录已弃用元素的标记。
/**
* @deprecated
* why it was deprecated
*/
@Deprecated
accessModifier returnType deprecatedMethodName() { ... }
示例 1:@Deprecated 注解示例
class Main {
/**
* @deprecated
* This method is deprecated and has been replaced by newMethod()
*/
@Deprecated
public static void deprecatedMethod() {
System.out.println("Deprecated method");
}
public static void main(String args[]) {
deprecatedMethod();
}
}
输出
Deprecated method
2。 @Override
@Override
注解指定子类的方法用相同的方法名、返回类型和参数列表覆盖超类的方法。
不强制使用 @Override
覆盖方法时。但是,如果我们使用它,如果在覆盖方法时出现错误(例如错误的参数类型),编译器会报错。
示例2:@Override 注解示例
class Animal {
// overridden method
public void display(){
System.out.println("I am an animal");
}
}
class Dog extends Animal {
// overriding method
@Override
public void display(){
System.out.println("I am a dog");
}
public void printMessage(){
display();
}
}
class Main {
public static void main(String[] args) {
Dog dog1 = new Dog();
dog1.printMessage();
}
}
输出
I am a dog
在这个例子中,通过制作一个对象 dog1 狗 类,我们可以调用它的方法 printMessage() 然后执行 display()
声明。
从 display()
在两个类中都有定义,子类 Dog 的方法 覆盖超类 Animal 的方法 .因此,display()
子类的被调用。
3。 @SuppressWarnings
顾名思义,@SuppressWarnings
注释指示编译器禁止在程序执行时生成警告。
我们可以指定要抑制的警告类型。可以抑制的警告是特定于编译器的,但有两类警告:弃用 并且未选中 .
为了抑制特定类别的警告,我们使用:
@SuppressWarnings("warningCategory")
例如,
@SuppressWarnings("deprecated")
为了抑制多类警告,我们使用:
@SuppressWarnings({"warningCategory1", "warningCategory2"})
例如,
@SuppressWarnings({"deprecated", "unchecked"})
类别 deprecated
指示编译器在我们使用不推荐使用的元素时抑制警告。
类别 unchecked
指示编译器在我们使用原始类型时抑制警告。
并且,未定义的警告将被忽略。例如,
@SuppressWarnings("someundefinedwarning")
示例 3:@SuppressWarnings 注释示例
class Main {
@Deprecated
public static void deprecatedMethod() {
System.out.println("Deprecated method");
}
@SuppressWarnings("deprecated")
public static void main(String args[]) {
Main depObj = new Main();
depObj. deprecatedMethod();
}
}
输出
Deprecated method
这里,deprecatedMethod()
已被标记为已弃用,并在使用时会给出编译器警告。通过使用 @SuppressWarnings("deprecated")
注解,我们可以避免编译器警告。
4。 @SafeVarargs
@SafeVarargs
annotation 断言被注释的方法或构造函数不会对其 varargs(可变数量的参数)执行不安全的操作。
我们只能在不能被覆盖的方法或构造函数上使用这个注解。这是因为覆盖它们的方法可能会执行不安全的操作。
在 Java 9 之前,我们只能在 final 或 static 方法上使用这个注解,因为它们不能被覆盖。我们现在也可以将此注解用于私有方法。
示例 4:@SafeVarargs 注释示例
import java.util.*;
class Main {
private void displayList(List<String>... lists) {
for (List<String> list : lists) {
System.out.println(list);
}
}
public static void main(String args[]) {
Main obj = new Main();
List<String> universityList = Arrays.asList("Tribhuvan University", "Kathmandu University");
obj.displayList(universityList);
List<String> programmingLanguages = Arrays.asList("Java", "C");
obj.displayList(universityList, programmingLanguages);
}
}
警告
Type safety: Potential heap pollution via varargs parameter lists Type safety: A generic array of List<String> is created for a varargs parameter
输出
Note: Main.java uses unchecked or unsafe operations. [Tribhuvan University, Kathmandu University] [Tribhuvan University, Kathmandu University] [Java, C]
这里,List
... lists
指定 List
类型的可变长度参数 .这意味着方法 displayList()
可以有零个或多个参数。
上面的程序编译没有错误,但在 @SafeVarargs
时给出警告 没有使用注解。
当我们使用 @SafeVarargs
上例中的注解,
@SafeVarargs private void displayList(List<String>... lists) { ... }
我们得到相同的输出,但没有任何警告。当我们使用这个注解时,未检查的警告也会被抑制。
5。 @FunctionalInterface
Java 8首先引入了这个@FunctionalInterface
注解。这个注解表明使用它的类型声明是一个功能接口。一个函数式接口只能有一个抽象方法。
示例 5:@FunctionalInterface 注解示例
@FunctionalInterface
public interface MyFuncInterface{
public void firstMethod(); // this is an abstract method
}
如果我们再添加一个抽象方法,比如说
@FunctionalInterface
public interface MyFuncInterface{
public void firstMethod(); // this is an abstract method
public void secondMethod(); // this throws compile error
}
现在,当我们运行程序时,我们会得到如下警告:
Unexpected @FunctionalInterface annotation @FunctionalInterface ^ MyFuncInterface is not a functional interface multiple non-overriding abstract methods found in interface MyFuncInterface
不强制使用 @FunctionalInterface
注解。编译器会将任何满足函数式接口定义的接口视为函数式接口。
我们使用这个注解来确保函数式接口只有一个抽象方法。
但是,它可以有任意数量的默认和静态方法,因为它们有一个实现。
@FunctionalInterface
public interface MyFuncInterface{
public void firstMethod(); // this is an abstract method
default void secondMethod() { ... }
default void thirdMethod() { ... }
}
自定义注解
也可以创建我们自己的自定义注解。
它的语法是:
[Access Specifier] @interface<AnnotationName> { DataType <Method Name>() [default value]; }
以下是您需要了解的自定义注解:
- 可以使用
@interface
创建注解 后跟注释名称。 - 注解可以包含看起来像方法但没有实现的元素。
- 默认值是可选的。参数不能为空值。
- 方法的返回类型可以是原始、枚举、字符串、类名或这些类型的数组。
示例 6:自定义注解示例
@interface MyCustomAnnotation {
String value() default "default value";
}
class Main {
@MyCustomAnnotation(value = "programiz")
public void method1() {
System.out.println("Test method 1");
}
public static void main(String[] args) throws Exception {
Main obj = new Main();
obj.method1();
}
}
输出
Test method 1
元注释
元注释是应用于其他注释的注释。
1。 @保留
@Retention
annotation 指定注释可用的级别。
它的语法是:
@Retention(RetentionPolicy)
保留政策有 3 种类型:
- RetentionPolicy.SOURCE - 注解仅在源代码级别可用,并被编译器忽略。
- RetentionPolicy.CLASS - 注解在编译时可供编译器使用,但被 Java 虚拟机 (JVM) 忽略。
- RetentionPolicy.RUNTIME - 注解可用于 JVM。
例如,
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation{ ... }
2。 @记录
默认情况下,官方 Java 文档中不包含自定义注解。为了在 Javadoc 文档中包含我们的注解,我们使用 @Documented
注释。
例如,
@Documented
public @interface MyCustomAnnotation{ ... }
3。 @目标
我们可以使用 @Target
限制注释应用于特定目标 注释。
它的语法是:
@Target(ElementType)
ElementType
可以有以下类型之一:
元素类型 | 目标 |
---|---|
ElementType.ANNOTATION_TYPE | 注解类型 |
ElementType.CONSTRUCTOR | 构造函数 |
ElementType.FIELD | 字段 |
ElementType.LOCAL_VARIABLE | 局部变量 |
ElementType.METHOD | 方法 |
ElementType.PACKAGE | 包 |
ElementType.PARAMETER | 参数 |
ElementType.TYPE | 类的任何元素 |
例如,
@Target(ElementType.METHOD)
public @interface MyCustomAnnotation{ ... }
在这个例子中,我们限制了这个注解的使用仅限于方法。
注意: 如果未定义目标类型,则注解可用于任何元素。
4。 @继承
默认情况下,注解类型不能从超类继承。但是,如果我们需要将注解从超类继承到子类,我们使用 @Inherited
注释。
它的语法是:
@Inherited
例如,
@Inherited
public @interface MyCustomAnnotation { ... }
@MyCustomAnnotation
public class ParentClass{ ... }
public class ChildClass extends ParentClass { ... }
5。 @可重复
已被 @Repeatable
标记的注解 可以多次应用于同一个声明。
@Repeatable(Universities.class)
public @interface University {
String name();
}
@Repeatable
中定义的值 annotation 是容器注解。容器注解有一个变量 value 上述可重复注释的数组类型。这里,Universities
是包含注释类型。
public @interface Universities {
University[] value();
}
现在,@University
注解可以在同一个声明中多次使用。
@University(name = "TU")
@University(name = "KU")
private String uniName;
如果我们需要检索注解数据,我们可以使用Reflection API。
要检索注释值,我们使用 getAnnotationsByType()
或 getAnnotations()
反射 API 中定义的方法。
java