一、注解基础知识点
定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是 JDK1.5 及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
作用分类:
①编写文档:通过代码里标识的元数据生成文档【生成文档 doc 文档】
② 代码分析:通过代码里标识的元数据对代码进行分析【使用反射】
③编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】
---以上来自百度百科介绍
二、元注解
专门(即只能)用于对注解进行注解的,称为元注解,它共有 5 个:@Target,@Retention,@Documented,@Inherited,@Repeatable
@Target:描述了注解修饰的对象范围,取值在 java.lang.annotation.ElementType 中定义。常用包括:
METHOD:用于描述方法
PACKAGE:用于描述包
PARAMETER:用于描述方法变量
TYPE:用于描述类、接口或 enum 类
@Retention :设定注解保留时间,取值在 java.lang.annotation.RetentionPolicy 中定义,常用包括:
@Documented: 表示 Java doc 文档记录。
@Inherited:表示注解会被自动继承。
@Repeatable:是 JDK 8 中新加入的,该注解可以在同一地方被多次使用。
三、自定义注解使用
1、定义注解
//颜色注解
@Target ({ElementType.FIELD,ElementType.METHOD})// 表明该注解可以标注到,属性、方法上
@Retention (RetentionPolicy.RUNTIME)// 表明该注解会保留到运行时
@Inherited //表示该注解可以被继承
@Documented //表明该注解会被生成到javadoc中
public @interface ColorAnnotation {
enum COLOR{RED,GREEN}
String value() default " xx color";
COLOR color() default COLOR.RED;
}
//用来备注的注解
@Target ({ElementType.METHOD,ElementType.FIELD})
@Retention (RetentionPolicy.RUNTIME)
public @interface Description {
String value() default "";
}
@Target ({ElementType.TYPE,ElementType.METHOD})
@Retention (RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
String value() default "ff";
}
复制代码
2、注解的使用
/**
* @Description: Box
* @Author: 青衣醉
* @Date: 2022/7/20 4:48 下午
*/
@Data
@AllArgsConstructor
public class Box {
@ColorAnnotation(value = "绿色",color = ColorAnnotation.COLOR.GREEN)
String name;
@Description("高")
Integer high;
@Description("宽")
Integer width;
@Description("礼盒")
String desc;
}
复制代码
3、注解的读取
注解的读取一般是通过反射机制来时实现的,Class、Method、Field 对象都有个 getAnnotation()方法,可以获取各自位置上的注解信息。
/**
* @Description: AnnotationController
* @Author: 青衣醉
* @Date: 2022/7/20 2:07 下午
*/
@RestController
@RequestMapping
public class AnnotationController {
@SneakyThrows
@Test
@MyAnnotation("我的盒子是一个")
public void test(){
Box box = new Box ("苹果",10,20,null);
Class<Box> boxClass = (Class<Box>) box.getClass ();
//获取方法上的注解
MyAnnotation test = this.getClass ().getMethod ("test").getAnnotation (MyAnnotation.class);
//获取属性上的注解
ColorAnnotation colorField = boxClass.getDeclaredField ("name").getAnnotation (ColorAnnotation.class);
//获取属性上的注解
Map<String, Description> fieldMap = this.getFieldMapAnnotatedWith (boxClass, Description.class);
StringBuilder sp = new StringBuilder (test.value ());
String s = sp.append (fieldMap.get ("high").value ())
.append (box.getHigh ())
.append (",")
.append (fieldMap.get ("width").value ())
.append (",")
.append (box.getWidth ())
.append (",")
.append (colorField.value ())
.append (box.getName ())
.append (fieldMap.get ("desc").value ()).toString ();
System.out.println (s);
}
/**
*获取class对象中使用了annotation注解的所有属性集合
*返回 key为属性名,value为注解对象的map集合
*/
private <T extends Annotation >Map<String,T> getFieldMapAnnotatedWith(Class<? extends Object> object, Class<T> annotation) {
if (Object.class.equals (object)) {
return Collections.emptyMap ();
}
Field[] declaredFields = object.getDeclaredFields ();
return Arrays.stream (declaredFields)
.filter (field -> field.getAnnotation (annotation) != null)
.collect (Collectors.toMap (field -> field.getName (), field -> field.getAnnotation (annotation)));
}
/**
*获取class对象中使用了annotation注解的所有属性对象集合
*/
private <T extends Annotation >Set<Field> getFieldAnnotatedWith(Class<? extends Object> object, Class<T> annotation) {
if (Object.class.equals (object)) {
return Collections.emptySet ();
}
Field[] declaredFields = object.getDeclaredFields ();
return Arrays.stream (declaredFields)
.filter (field -> field.getAnnotation (annotation) != null)
.collect (Collectors.toSet ());
}
}
复制代码
输出结果:
评论