注解其实就是一个标记,是一种提供元数据的机制,用于给代码添加说明信息。可以标记在类上、方法上、属性上等,标记自身也可以设置一些值。
注解本身不影响程序的逻辑执行,但可以通过工具或框架来利用这些信息进行特定的处理,如代码生成、编译时检查、运行时处理等。
扩展知识
自定义注解
注解的定义使用@interface
关键字。
@interface
用来声明一个注解。value
是注解的一个成员变量,default
关键字可以为成员变量设置默认值。age
也是一个成员变量,但没有默认值,所以在使用时必须提供这个值。
处理注解
- 编译时处理:使用javax.annotation.processing 包进行注解处理器的开发
- 运行时处理:使用反射机制访问注解,通过Class.getAnnotation()或Field.getAnnotation()等方法获取注解信息
元注解
Java提供了四种元注解来帮助定义其他注解:
@Retention
: 定义注解的生命周期(SOURCE, CLASS, RUNTIME)。@Target
: 定义注解可以应用的目标(类、方法、字段等)。@Documented
: 标记注解是否应被包含在JavaDoc中。@Inherited
: 允许子类继承父类中的注解。
注解的三大保留策略
SOURCE:注解只存在于源码中,在编译时被丢弃
CLASS:注解只存在编译期,也就是编译后的.class文件中,但运行时不会被JVM加载
RUNTIME:注解在整个生命周期内都保留,运行时可以通过反射获取
例如这个注解,就是专门给编译器用的,class文件是不会有这个注解的
再比如Spring的Autowired,是RUNTIME的,在运行时可以通过反射获取注解的信息
Target
- TYPE:类、接口、注解或枚举
- FIELD:字段(包括枚举常量)
- METHOD:方法
- PARAMETER:方法参数
- CONSTRUCTOR:构造方法
- LOCAL_VARIABLE:局部变量
- ANNOTATION_TYPE:注解类型
- PACKAGE:包
运行时可以用反射获取注解的成员信息
public class AnnotationTest {
public static void main(String[] args) {
new AnnotationTest().introduce();
}
@MyAnnotation(age = 20)
public void introduce(){
Method introduce = null;
try {
introduce = AnnotationTest.class.getDeclaredMethod("introduce");
}catch (NoSuchMethodException e){
e.printStackTrace();
}
if (introduce.isAnnotationPresent(MyAnnotation.class)){
MyAnnotation annotation = introduce.getAnnotation(MyAnnotation.class);
System.out.println(annotation.value() + "第一次遇见他,是" + annotation.age() + "岁");
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
// 定义注解的成员变量
String value() default "王心妍";
int age();
}
标签:面试题,Java,introduce,MyAnnotation,public,注解,046,RUNTIME,class
From: https://blog.csdn.net/lklalmq/article/details/144707020