自定义注解的简单使用
自定义注解的简单使用
定义注解
先看代码例子:
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.FIELD)
public @interface MyTestAnnotation {
String value();
}
自定义注解时,需要添加两个重要的注解:
-
@Retention
用于标识注解能够保留多长时间,默认值为 RetentionPolicy.CLASS.
关于RetentionPolicy枚举类:
public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. * 保留在源文件种 */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. * 保留在class文件中,加载到JVM时丢失 */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement * 保留在程序运行期间. */ RUNTIME }RetentionPolicy.RUNTIME 在运行期间也会有效.一般....就用它.
也许另外两个时辅助作用.
-
@Target
用域标识注解可以使用在什么地方.枚举类中讲的很清楚了,这里再贴一下.
关于ElementType枚举类:
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Formal parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE, /** * Type parameter declaration * * @since 1.8 */ TYPE_PARAMETER, /** * Use of a type * * @since 1.8 */ TYPE_USE, /** * Module declaration. * * @since 9 */ MODULE }
使用
-
自定义一个实体类
public class TestModel { @MyTestAnnotation("我的注解") private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } @Override public String toString() { return "TestModel{" + "value='" + value + '\'' + '}'; } } -
运行测试方法查看输出结果
public class TestAnnotation { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { TestModel testModel1 = new TestModel(); testModel1.setValue("我自己放的value"); TestModel testModel2 = new TestModel(); //setAnnotationValue(testModel2);//下面的步骤需要用到的方法 System.out.println(testModel1); System.out.println(">>>>>>>>>>>>>>>>>>"); System.out.println(testModel2); } }结果:
TestModel{value='我自己放的value'} >>>>>>>>>>>>>>>>>> TestModel{value='null'}它并没有生效.
-
丢失的步骤
仅仅是写上注解,代码中并没有自动地去识别这个注解,然后去做想要地事情.
我们需要通过代码来检测注解,然后实现自己的逻辑.
这里通过反射来进行默认值的设置.
private static void setAnnotationValue(Object o) throws NoSuchFieldException, IllegalAccessException { Field field = o.getClass().getDeclaredField("value"); field.setAccessible(true); if(field.isAnnotationPresent(MyTestAnnotation.class)){ String settingValue = (String) field.get(o);//这里通过反射拿到value属性的值 if(!StringUtils.isEmpty(settingValue)){//如果value属性不为空,就返回 return; } MyTestAnnotation myTestAnnotation = field.getAnnotation(MyTestAnnotation.class); String value = myTestAnnotation.value();//拿到注解中设置的值 field.set(o,value);//将注解中的值赋值给当前对象 } }再次查看输出结果:
TestModel{value='我自己放的value'} >>>>>>>>>>>>>>>>>> TestModel{value='我的注解'}

浙公网安备 33010602011771号