注解的定义
一、理论说明
1. 注解的定义
Java 注解是从 JDK 5.0 开始引入的一种元数据机制,它可以为代码添加额外的信息,这些信息不影响程序的运行逻辑,但可以在编译期、类加载期或运行期被读取和处理。注解本质上是一种特殊的接口,所有注解都自动继承java.lang.annotation.Annotation
接口。注解可以应用于类、方法、字段、参数等程序元素上,用于实现如代码检查、配置信息、生成文档等功能。
2. 内置注解与自定义注解的区别
- 定义方式:
- 内置注解是 Java 语言自带的,在
java.lang
、java.lang.annotation
等包中已经定义好,例如@Override
、@Deprecated
、@SuppressWarnings
等,开发者可以直接使用。 - 自定义注解需要开发者自己使用
@interface
关键字来定义新的注解类型,通过元注解(如@Retention
、@Target
等)来指定注解的保留策略和适用范围 。
- 内置注解是 Java 语言自带的,在
- 功能特性:
- 内置注解具有特定的、固定的功能。比如
@Override
用于确保方法正确重写父类方法,编译器会进行检查;@Deprecated
用于标记不建议使用的代码元素,提醒开发者避免使用 。 - 自定义注解功能更加灵活,开发者可以根据具体需求定义注解的属性和处理逻辑,用于实现特定的业务逻辑,如自定义的权限控制、数据校验等。
- 内置注解具有特定的、固定的功能。比如
- 使用场景:
- 内置注解适用于通用的、常见的代码标注场景,是 Java 语言为了提高代码质量和开发效率提供的基础工具 。
- 自定义注解适用于项目中特定的、个性化的需求,例如在 Web 开发中定义注解来处理请求日志记录、在持久化层定义注解来映射数据库表结构等。
二、常用注解与元注解
1. 内置常用注解
@Override
用于标识一个方法是重写父类的方法。如果被注解的方法并非真正重写父类方法,编译器会报错。例如:
class Animal {public void speak() {System.out.println("动物发出声音");}
}class Dog extends Animal {@Overridepublic void speak() {System.out.println("狗汪汪叫");}
}
@Deprecated
用于标记不再建议使用的类、方法或字段。当其他开发者使用被该注解标记的元素时,编译器会给出警告。例如:
@Deprecated
public void oldMethod() {System.out.println("这是一个不再建议使用的方法");
}
@SuppressWarnings
用于抑制编译器产生的警告信息。可以通过指定警告类型,如unchecked
(抑制未检查类型转换警告)、deprecation
(抑制使用已过时元素的警告)等。例如:
import java.util.ArrayList;
import java.util.List;public class Main {@SuppressWarnings("unchecked")public static void main(String[] args) {List list = new ArrayList();list.add("元素");}
}
2. 元注解
@Retention
用于指定注解的保留策略,即注解在什么阶段还存在。@Retention
有三个取值:
四、面试题
题目:
答案:
五、自我总结
通过对 Java 注解的学习,我们掌握了一种强大且灵活的元数据添加方式。内置注解在日常开发中能有效提高代码质量和规范性,而自定义注解结合元注解,为满足个性化业务需求提供了有力工具。掌握@Override
、@Deprecated
、@SuppressWarnings
等内置注解,以及@Retention
、@Target
等元注解的使用,能让我们在实际编程中根据不同场景合理运用注解。在实际应用场景中,如代码规范检查、框架配置、日志记录等方面,注解都能发挥重要作用。合理使用注解不仅可以使代码结构更清晰,还能提高代码的可维护性和扩展性,在大型项目开发和框架设计中具有重要意义 。
RetentionPolicy.SOURCE
:注解只保留在源文件中,编译成字节码文件时就会被丢弃,例如@Override
注解。RetentionPolicy.CLASS
:注解保留在字节码文件中,但在运行时无法获取,这是默认的保留策略。RetentionPolicy.RUNTIME
:注解不仅保留在字节码文件中,在运行时也可以通过反射获取和处理。例如:import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME) @interface MyRuntimeAnnotation {}
@Target
用于指定注解可以应用的程序元素类型,如类、方法、字段等。
@Target
的取值包括:ElementType.TYPE
:应用于类、接口、枚举等类型。ElementType.METHOD
:应用于方法。ElementType.FIELD
:应用于字段。
例如:import java.lang.annotation.ElementType; import java.lang.annotation.Target;@Target(ElementType.METHOD) @interface MyMethodAnnotation {}
三、应用实例
以下代码展示了自定义注解及其使用和处理:
import java.lang.annotation.*; import java.lang.reflect.Method;// 定义自定义注解 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @interface Loggable {String value() default ""; }class Calculator {@Loggable("执行加法运算")public int add(int a, int b) {return a + b;}public int subtract(int a, int b) {return a - b;} }public class Main {public static void main(String[] args) throws NoSuchMethodException {Calculator calculator = new Calculator();Method addMethod = calculator.getClass().getMethod("add", int.class, int.class);if (addMethod.isAnnotationPresent(Loggable.class)) {Loggable loggable = addMethod.getAnnotation(Loggable.class);System.out.println("注解信息: " + loggable.value());}int result = calculator.add(3, 5);System.out.println("计算结果: " + result);} }
代码解释
- 定义自定义注解:使用
@interface
关键字定义Loggable
注解,通过@Retention(RetentionPolicy.RUNTIME)
指定该注解在运行时可用,@Target(ElementType.METHOD)
指定该注解只能应用于方法上,同时定义了一个value
属性。 - 使用注解:在
Calculator
类的add
方法上使用@Loggable
注解,并设置value
属性为 “执行加法运算” 。 - 处理注解:在
main
方法中,通过反射获取add
方法,使用isAnnotationPresent
方法检查该方法是否存在Loggable
注解。如果存在,则使用getAnnotation
方法获取注解实例,并输出注解的value
属性值,最后调用add
方法进行计算并输出结果。