当前位置 : 主页 > 编程语言 > java >

JAVA自定义注解详情

来源:互联网 收集:自由互联 发布时间:2021-11-19
目录 原理: 元注解: @Retention参数讲解: 案例: 给一个类的String属性设置默认值 总结 原理: 注解的本质是继承Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类.而我们通过反
目录
  • 原理:
  • 元注解:
    • @Retention参数讲解:
  • 案例:
    • 给一个类的String属性设置默认值
  • 总结

    原理:

    注解的本质是继承Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类.而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象Proxy1,通过动态代理对象,调用自定义注解(接口)的方法,最终会调用AnnotationInvocationHandler 的invoke方法.

    元注解:

    • @Documented:是否将注解包含到JavaDoc中
    • @Retention:什么时候使用该注解,表明注解的生命周期
    • @Target:注解用于什么地方
    • @Inherited:是否允许子类继承改注解

    @Retention参数讲解:

    RetentionPolicy.SOURCE:在编译阶段丢弃,这些注解在编译结束后就不会再有意义,所以它不会写入字节码.比如@Override, @SuppressWarnings都属于这类注解。

    RetentionPolicy.CLASS:在类加载的时候丢弃, 包含在类文件中

    RetentionPolicy.RUNTIME:包含在类文件中,在运行时可以被获取到

    @Target:参数讲解:

    ElementType.TYPE:用于类,接口,枚举

    ElementType.FIELD:应用于属性

    ElementType.METHOD:应用于方法

    ElementType.PARAMETER:用于方法的形式参数

    ElementType.CONSTRUCTOR:用于构造函数

    ElementType.LOCAL_VARIABLE:应用于局部变量

    ElementType.ANNOTATION_TYPE:应用于注解类型

    ElementType.PACKAGE:应用于包

    ElementType.TYPE_PARAMETER:应用于类型变量(1.8新增)

    ElementType.TYPE_USE:1.8版本新增,应用于任何使用类型的语句中

    案例:

    给一个类的String属性设置默认值

    @Documented
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ObjectFlag {
        //默认值
        String value() default "默认值1";
    }
    public class ObjectTest {
        @ObjectFlag
        String name;
        @ObjectFlag
        Integer age;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Integer getAge() {
            return age;
        }
        public void setAge(Integer age) {
            this.age = age;
        }
    public class ObjectRun {
      public static <T> T setValueField(T t) throws IllegalAccessException {
            Class<?> cls = t.getClass();
            Field[] fields = cls.getDeclaredFields();
            for (Field field : fields) {
                boolean hasConfigField = field.isAnnotationPresent(ObjectFlag.class);
                field.setAccessible(true);//设置可以访问私有变量
                //若属性上有注解,使用注解的值作为key去配置文件中查找
                if (hasConfigField) {
                    //获取注解的默认值
                    Object annoValue = field.getAnnotation(ObjectFlag.class).value();
                    System.out.println("当前的属性名称为:" + field.getName());
                    System.out.println("当前属性类型:" + field.getGenericType().toString());
                    //获取到属性的数据类型
                    String type = field.getGenericType().toString();
                    if (type.endsWith("String")) {//如果是字符串类型
                        field.set(t, annoValue.toString());
                    }
                } else {  //若属性上没有注解,则使用属性名作为key去配置文件中查找
                    System.out.println("属性" + field.getGenericType().toString() + "没有该注解");
                }
            }
            return t;
        }
    }

    运行结果:

    总结

    本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之际的更多内容!

    上一篇:C++ map详解
    下一篇:没有了
    网友评论