Java注解源码分析,实现自定义注解通过反射获取

这篇具有很好参考价值的文章主要介绍了Java注解源码分析,实现自定义注解通过反射获取。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Annotation 源码分析

  • JDK5.0 引入,可以通过反射机制动态获取,大量应用于java框架中

  • 内置注解

    • @Override

      • 重写父类方法时
      @Target(ElementType.METHOD)  //该注解只能作用于方法
      @Retention(RetentionPolicy.SOURCE)  //在编译时起作用,静态检查
      public @interface Override {
          
      }
      
    • @Deprecated

      • 使用它存在风险,可能导致错误
      • 可能在未来版本中不兼容
      • 可能在未来版本中删除
      • 一个更好和更高效的方案已经取代它
      @Documented  //表明可以生成为javadoc文档
      @Retention(RetentionPolicy.RUNTIME)  //在运行时起作用
      //可以作用于构造函数,属性,局部变量,方法,包,模块,参数,类型上
      @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
      public @interface Deprecated {
          /**
           * Returns the version in which the annotated element became deprecated.
           * The version string is in the same format and namespace as the value of
           * the {@code @since} javadoc tag. The default value is the empty
           * string.
           *
           * @return the version string
           * @since 9
           */
          String since() default "";  //一个属性since  String类型,默认为空
      
          /**
           * Indicates whether the annotated element is subject to removal in a
           * future version. The default value is {@code false}.
           *
           * @return whether the element is subject to removal
           * @since 9
           */
          boolean forRemoval() default false;  //是否已删除
      }
      
    • @SuppressWarnings

      • 告诉编译器忽略指定的警告,不用在编译完成后出现警告信息。
    //可以做用于类型,属性,方法,参数,构造函数,局部变量,模块
    @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})
    //作用于编译期
    @Retention(RetentionPolicy.SOURCE)
    public @interface SuppressWarnings {
        /**
         * The set of warnings that are to be suppressed by the compiler in the
         * annotated element.  Duplicate names are permitted.  The second and
         * successive occurrences of a name are ignored.  The presence of
         * unrecognized warning names is <i>not</i> an error: Compilers must
         * ignore any warning names they do not recognize.  They are, however,
         * free to emit a warning if an annotation contains an unrecognized
         * warning name.
         *
         * <p> The string {@code "unchecked"} is used to suppress
         * unchecked warnings. Compiler vendors should document the
         * additional warning names they support in conjunction with this
         * annotation type. They are encouraged to cooperate to ensure
         * that the same names work across multiple compilers.
         * @return the set of warnings to be suppressed
         */
        String[] value(); //String类型数组 写为value时在写注解时可以省略value= 
    }
    
    
    value常见取值:
        all, to suppress all warnings抑制所有警告
        boxing, to suppress warnings relative to boxing/unboxing operations抑制与装箱/拆箱操作相关的警告
        cast, to suppress warnings relative to cast operations抑制与转换操作相关的警告
        dep-ann, to suppress warnings relative to deprecated annotation抑制与弃用注释相关的警告
        deprecation, to suppress warnings relative to deprecation抑制与弃用相关的警告
        fallthrough, to suppress warnings relative to missing breaks in switch statements抑制与 switch 语句中缺少中断相关的警告
        finally, to suppress warnings relative to finally block that don’t return抑制相对于 finally 块不返回的警告
        hiding, to suppress warnings relative to locals that hide variable抑制与隐藏变量的局部变量相关的警告
        incomplete-switch, to suppress warnings relative to missing entries in a switch statement (enum case)抑制与 switch 语句中缺失条目相关的警告(枚举大小写)
        nls, to suppress warnings relative to non-nls string literals抑制与非 nls 字符串文字相关的警告
        null, to suppress warnings relative to null analysis抑制与空分析相关的警告
        rawtypes, to suppress warnings relative to un-specific types when using generics on class params 在类参数上使用泛型时抑制与非特定类型相关的警告
        restriction, to suppress warnings relative to usage of discouraged or forbidden references抑制与使用不鼓励或禁止的引用有关的警告
        serial, to suppress warnings relative to missing serialVersionUID field for a serializable class抑制与可序列化类的缺少 serialVersionUID 字段相关的警告
        static-access, to suppress warnings relative to incorrect static access抑制与不正确的静态访问相关的警告
        synthetic-access, to suppress warnings relative to unoptimized access from inner classes抑制与来自内部类的未优化访问相关的警告
        unchecked, to suppress warnings relative to unchecked operations抑制与未经检查的操作相关的警告
        unqualified-field-access, to suppress warnings relative to field access unqualified抑制与不合格的字段访问相关的警告
        unused, to suppress warnings relative to unused code抑制与未使用代码相关的警告
    
    
  • 元注解:修饰注解的注解

    • 首先解释两个枚举类 1.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
      }
      
    • 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,
      
          /**
           * 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
      }
      
      
    • @Target

      @Documented
      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.ANNOTATION_TYPE)
      public @interface Target {
          /**
           * Returns an array of the kinds of elements an annotation type
           * can be applied to.
           * @return an array of the kinds of elements an annotation type
           * can be applied to
           */
          ElementType[] value();  //枚举类ElementType数组,表明注解可以作用于多个位置
      }
      
      
    • @Retention

      @Documented
      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.ANNOTATION_TYPE)
      public @interface Retention {
          /**
           * Returns the retention policy.
           * @return the retention policy
           */
          RetentionPolicy value(); //指明注解的作用生命周期,单个枚举类 RetentionPolicy
      }
      
    • @Documented

      • 默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了 @Documented,则它会被 javadoc 之类的工具处理, 所以注解类型信息也会被包括在生成的文档中,是一个标记注解,没有成员。
      @Documented
      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.ANNOTATION_TYPE)
      public @interface Documented {
          //为空
      }
      
    • @Inherited文章来源地址https://www.toymoban.com/news/detail-435626.html

      @Documented
      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.ANNOTATION_TYPE)
      public @interface Inherited {
          //为空
      }
      

自定义注解并通过反射获取信息

  • @TableName 表明实体类与哪个数据库表对应
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {
    String value() default "";
}
//在实体类上使用自定义注解
@TableName("cat")
public class Cat {
    private int age;
    private String name;
    public static void main(String[] args) throws ClassNotFoundException {
        //通过一种获取Class对象的方式 forName
        Class<?> c1 = Class.forName("org.yrdm.ch1.Cat");
        //获取所有注解并打印
        Annotation[] annotations = c1.getDeclaredAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
		//获取特定注解并输出value值
        TableName anno = c1.getDeclaredAnnotation(TableName.class);
        String value = anno.value();
        System.out.println(value);
    }
}

运行结果:
    @org.yrdm.ch1.TableName(value="cat")
	cat

到了这里,关于Java注解源码分析,实现自定义注解通过反射获取的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • spring boot 使用AOP+自定义注解+反射实现操作日志记录修改前数据和修改后对比数据,并保存至日志表

    使用FieldMeta自定义注解,看个人业务自行觉得是否需要重新定义实体 实现类 :通过该实现类获取更新前后的数据。 该实现类的实现原理为:获取入参出入的id值,获取sqlSessionFactory,通过sqlSessionFactory获取selectByPrimaryKey()该方法,执行该方法可获取id对应数据更新操作前后的数

    2024年01月23日
    浏览(41)
  • 【注解和反射】获取类运行时结构

    继上一篇博客【注解和反射】类加载器-CSDN博客 目录 七、获取类运行时结构 测试 getFields()和getDeclaredFields() getMethods()和getDeclaredMethods() 获取类运行时结构通常指的是在Java等面向对象编程语言中,使用反射(Reflection)机制来检查类、接口、字段(Field)和方法(Method)等程序

    2024年04月28日
    浏览(23)
  • SpringBoot通过自定义注解实现多数据源

    ✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Java从入门到精通 ✨特色专栏: MySQL学习 🥭本文内容:SpringBoot通过自定义注解实现多数据源 📚个人知识库: Leo知识库,欢迎大家访问 大家好

    2024年02月03日
    浏览(38)
  • Java AOP 通过注解实现切面及通过注解改变返回值

    学习过java的小伙伴都知道Spring的重要知识点之一就是AOP,AOP也就是切面编程,切面编程它能够帮助我们实现非侵入式的功能增强,解耦现有的业务逻辑和要新增的功能增强。 实际应用中的场景 事务管理、拦截器、日志处理、权限控制等。 AOP的增强方式 前置增强、后置增强

    2024年02月14日
    浏览(29)
  • 用反射实现自定义Java对象转化为json工具类

    传入一个object类型的对象 获取该对象的class类 getFields方法获取该类的所有属性 对属性进行遍历,并且拼接成Json格式的字符串,注意:通过属性名来推断方法名 获取Method实例 通过invoke方法调用 以User类进行测试   

    2024年02月11日
    浏览(30)
  • Java实现自定义注解

    (1)Java实现自定义注解其实很简单,跟类定义差不多,只是属性的定义可能跟我们平时定义的属性略有不同,这里会给大家详解,先来看代码: 上面代码就实现了一个 自定义注解 , 实现自定义注解需要最少指定 两个 基本条件 : ①注解的作用范围②注解的生命周期 ,那

    2023年04月19日
    浏览(28)
  • java注解与反射

    java注解与反射十分重要,是很多框架的底层 注解的作用: 注解的格式:@注释名,如@override表示重写方法,而且有些还可以添加一些参数值,如@SuppressWarnings(value=\\\"unchecjed\\\") 注解可以附加在package,class,method,field等上面,相当于添加了额外的辅助信息。可以通过反射机制编程

    2024年02月07日
    浏览(42)
  • java 自定义xss校验注解实现

    自定义一个注解@Xss。名字随意 validator校验类:XssValidator。这个校验类要和上面的@Xss注解上的 @Constraint(validatedBy = { XssValidator.class })对应 具体使用在某个字段上加上注解;形如: 然后在控制层中增加@Validated注解校验就可以了  以上代码实现后。会自动针对某些增加了@Xss字符

    2024年02月14日
    浏览(34)
  • Java补充内容(Junit 反射 注解)

    测试分类: 1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值。 2. 白盒测试:需要写代码的。关注程序具体的执行流程。 Junit使用:白盒测试 步骤: 定义一个测试类(测试用例) 建议: 测试类名:被测试的类名Test CalculatorTest 包名:xxx.xxx.xx.test cn.itcast.

    2024年02月16日
    浏览(30)
  • 【JAVA】单元测试、反射、注解、动态代理

    @Test 测试方法 @Before 用来修饰实例方法,该方法会在每一个测试方法执行之前执行一次。 @After 用来修饰实例方法,该方法会在每一个测试方法执行之后执行一次。 @Before Class 用来静态修饰方法,该方法会在所有测试方法之前只执行一次。 @After Class 用来静态修饰方法,该方法

    2024年02月11日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包