Java中自定义注解
2021-07-08 23:05
自定义注解
Java中自定义注解和创建一个接口相似,自定义注解的格式是以@interface为标志的。
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface SPI { /** * default extension name */ String value() default ""; }
我们知道java.lang.annotation包中有一个Annotation的接口,它是所有注解类型扩展的公共接口。那我们是否可以直接通过实现该接口来实现自定义注解呢?
import java.lang.annotation.Annotation; public class MyAnnotation implements Annotation { @Override public Class extends Annotation> annotationType() { return null; } }
发现Annotation接口中只有一个annotationType的方法,而且通过Annotation源码的注释我们可以发现答案是不能。
汉译即为:Annotaion被所有注解类型继承,但是要注意:手动扩展继承此接口的接口不会定义注解类型。另请注意,此接口本身不定义注解类型。
使用场景
自定义注解的使用场景很多,我们在造轮子写框架的过程经常会使用到,例如我最近就遇到了一个业务场景:像一些编辑业务信息的接口,产品要求信息编辑后的新旧值对比,对比的业务功能,我们的实现方式是拿到前端填写的Form表单(新值)和数据库中查询出来的Dto(旧值)通过反射技术获取到相同属性字段名,再比较属性值就可以得出新旧值。得到值之后我们也知道该字段的Dto中的字段名,但是如何将比较得到的新旧值字段的中文名返回给前端呢?例如:
public class Stedent { private String name; private int age; private String sex; //省略setter,getter }
比较后我们的结果是 name : “xiaoming “-> “daming”,age : 24 -> 26。但是我们不能直接将name和age返回给前端,他们需要的格式是:姓名: “xiaoming “-> “daming”,年龄 : 24 -> 26。这时候就可以考虑自定义一个注解@FieldName
,
@Deprecated @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface FieldName { String value() default ""; }
然后将该注解加在属性字段上面
public class Student { @FieldName(value = "姓名") private String name; @FieldName(value = "年龄") private int age; @FieldName(value = "性别") private String sex; //省略setter,getter }
之后就可以通过反射获取该字段中文名。
// 如果 oldField 属性值与 newField 属性值的内容不相同 if (!isEmpty(newValue)) { Mapmap = new HashMap(); String newFieldName = newField.getName(); if (newField.isAnnotationPresent(ApiModelProperty.class)) { ApiModelProperty apiModelPropertyAnno = newField.getAnnotation(ApiModelProperty.class); newFieldName = apiModelPropertyAnno.value(); else if (newField.isAnnotationPresent(FieldName.class)) { FieldName fieldNameAnno = newField.getAnnotation(FieldName.class); newFieldName = fieldNameAnno.name(); } map.put(FIELD_NAME, newFieldName); map.put(OLD_VALUE, oldValue); map.put(NEW_VALUE, newValue); list.add(map); }
上一篇:18.4 操作线程的方法