Java注解
Koyang 1/7/2022 Java后端
在面向对象中,Java的注解使用
# Java注解
JAVA 中有以下几个『元注解』:
@Target
:注解的作用目标@Retention
:注解的生命周期@Documented
:注解是否应当被包含在 JavaDoc 文档中@Inherited
:是否允许子类继承该注解
# @Target
@Target 用于指明被修饰的注解最终可以作用的目标是谁
@Target(value = {ElementType.FIELD})
其中,ElementType 是一个枚举类型,有以下一些值:
- ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上
- ElementType.FIELD:允许作用在属性字段上
- ElementType.METHOD:允许作用在方法上
- ElementType.PARAMETER:允许作用在方法参数上
- ElementType.CONSTRUCTOR:允许作用在构造器上
- ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上
- ElementType.ANNOTATION_TYPE:允许作用在注解上
- ElementType.PACKAGE:允许作用在包上
# @Retention
@Retention 用于指明当前注解的生命周期,它的基本定义如下:
@Retention(value = RetentionPolicy.RUNTIME
这里的 RetentionPolicy
依然是一个枚举类型,它有以下几个枚举值可取:
- RetentionPolicy.SOURCE:当前注解编译期可见,不会写入 class 文件
- RetentionPolicy.CLASS:类加载阶段丢弃,会写入 class 文件
- RetentionPolicy.RUNTIME:永久保存,可以反射获取
# @Documented
@Documented 注解修饰的注解,当我们执行 JavaDoc 文档打包时会被保存进 doc 文档,反之将在打包时丢弃。
# @Inherited
@Inherited 注解修饰的注解是具有可继承性的,也就说我们的注解修饰了一个类,而该类的子类将自动继承父类的该注解。
# 例子
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Codeyang
* @date 2022/1/8
*/
@Target(value = {ElementType.FIELD,ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Hello {
String value();
}
@Test
@Hello("hello")
public void TestAnnotationHello() throws NoSuchMethodException {
Class clazz = MyController.class;
Method method = clazz.getMethod("TestAnnotationHello");
System.out.println(method);
Hello hello= method.getAnnotation(Hello.class);
System.out.println(hello);
}
输出:
public void annotation.MyController.TestAnnotationHello() throws java.lang.NoSuchMethodException
@annotation.Hello(value=hello)
# 实现根据注解匹配方法
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE,ElementType.METHOD})//当前注解可以用在类,接口,枚举或方法上
@Retention(RetentionPolicy.RUNTIME) //JVM运行时期可以通过反射获取注解值
public @interface RequestMapping {//一个注解
String value() default "good";//是一个字段值
}
@RequestMapping("/stu")
public class MyController {
@RequestMapping("/getStuInfo")
public void select(){
System.out.println("查询学生信息");
}
@RequestMapping("/update")
public void update() {
System.out.println("更新学生信息");
}
@RequestMapping("/delete")
public void delete() {
System.out.println("删除学生信息");
}
@Test
public void TestAnnotation() {
String url="/delete";//模拟前端发送的请求路径
Class clazz=MyController.class;
if(clazz.isAnnotationPresent(RequestMapping.class)){//判断当前类上是否有RequestMapping注解
Method methods[]=clazz.getDeclaredMethods();//获取类中所有的方法
for(Method method:methods){
if(method.isAnnotationPresent(RequestMapping.class)){//判断当前方法是否有RequestMapping注解
RequestMapping requestMapping=method.getAnnotation(RequestMapping.class);//获取注解对象,目的是为了获取注解值
if(requestMapping.value().equals(url)){//全部匹配,找到请求对应的方法
try {
method.invoke(clazz.newInstance());//调用方法
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
}
}
}
}