面试题答案
一键面试自定义Java注解的一般步骤及元注解使用
- 定义注解:
使用
@interface
关键字来定义一个新的注解。例如:
public @interface MyAnnotation {
}
- 添加元素: 注解可以包含元素(类似于方法声明),元素需要有默认值(除非在使用注解时显式赋值)。例如:
public @interface MyAnnotation {
String value() default "";
int count() default 0;
}
- 使用元注解:
元注解是用于注解其他注解的注解,常见的元注解有:
@Retention
:指定注解的保留策略,即注解在什么阶段存在。有三个取值:RetentionPolicy.SOURCE
:注解只在源码阶段保留,编译时会被丢弃。RetentionPolicy.CLASS
:注解在编译后的字节码文件中存在,但在运行时JVM不会保留,这是默认值。RetentionPolicy.RUNTIME
:注解在运行时仍然存在,程序可以通过反射获取并使用注解信息。例如:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "";
int count() default 0;
}
- **`@Target`**:指定注解可以应用的目标类型,如类、方法、字段等。取值包括:
- **`ElementType.TYPE`**:类、接口、枚举。
- **`ElementType.METHOD`**:方法。
- **`ElementType.FIELD`**:字段。
- 等等。例如:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String value() default "";
int count() default 0;
}
- **`@Documented`**:表示该注解会被包含在JavaDoc中。
- **`@Inherited`**:表示子类会继承父类的该注解(仅针对类注解)。
Java注解在运行时的解析及结合反射机制发挥作用
- 获取注解信息:
当注解的保留策略为
RetentionPolicy.RUNTIME
时,可以通过反射来获取注解信息。假设我们有一个使用了上述MyAnnotation
注解的方法:
public class MyClass {
@MyAnnotation(value = "test", count = 5)
public void myMethod() {
// 方法实现
}
}
通过反射获取方法上的注解信息:
import java.lang.reflect.Method;
public class AnnotationParser {
public static void main(String[] args) throws NoSuchMethodException {
Class<MyClass> myClass = MyClass.class;
Method method = myClass.getMethod("myMethod");
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
if (annotation != null) {
System.out.println("Value: " + annotation.value());
System.out.println("Count: " + annotation.count());
}
}
}
- 基于注解信息执行逻辑:
获取到注解信息后,可以根据注解的元素值执行不同的逻辑。例如,根据
count
的值来决定执行某个操作的次数:
import java.lang.reflect.Method;
public class AnnotationParser {
public static void main(String[] args) throws NoSuchMethodException {
Class<MyClass> myClass = MyClass.class;
Method method = myClass.getMethod("myMethod");
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
if (annotation != null) {
for (int i = 0; i < annotation.count(); i++) {
System.out.println("Executing based on annotation, iteration " + i);
}
}
}
}
通过反射获取类、方法、字段等对象上的注解,然后根据注解中的元素值进行相应的处理,从而使注解在运行时发挥作用。