美文网首页
Java注解类 - 注解类入门

Java注解类 - 注解类入门

作者: 小赵营 | 来源:发表于2019-07-18 23:24 被阅读0次

    茨威格在《人类群星闪耀时》写到那些改变历史进程的小人物。原本默默无闻,却一鸣惊人。我们日常生活中,容易被忽略的细节,当真正了解它时,顿时"斯巴达"了。'Java注解类'在我心里就属于貌不惊人狠角色。

    本文介绍注解类简介和如何自定义自己的注解类。

    概要

    单纯说注解,注解本身意义并不大。作为标签对对象的注释,比如生成doc的注释,函数已废弃.... 简单说和注释没啥区别。而它发挥巨大作用的是:注解解释类,也就是相关对代码进行解释的特定类。

    注解类神奇功效是:通过注解和反射这两者的结合使用达成的。现在很多流行的开源框架都是基于注解类实现。可关注下spring rpc.....等各种开源框架。

    本文内容包括:

    • 注解类的介绍
    • 自己动手写注解类

    认识注解类

    简单来说,注解类就是标签。只是标签分为不同的种类,对应的作用域和使用方式也千差万别。从功能上而言:这些标签分为: 基本注解、元注解、自定义注解。

    基本注解

    基本注解类是基于JVM虚拟机的语言,提供的系统注解。也是基本的通用注解类。
    比如自Java 1.5版本以来提供的@override@deprecated,和 1.8版本的@FunctionalInterface ...

    元注解

    在我们翻看注解类源码的时候,总会有如下定义:

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface FunctionalInterface {}
    

    @Documented,@Retention(RetentionPolicy.RUNTIME),@Target(ElementType.TYPE) 使用过注解,我们知道这些都是注解。为基本注解作注,意味者特殊身份 -- 元注解。

    所以元注解定义是: 元注解是标记其他注解注解。就有像标识性别是人必须的一个标签。元注解就像性别。描述人必须有性别,那么注解类也需要元注解标注。

    元注解不能作用于具体函数变量等,如下操作报错@Target not applicatable to type

        @Target() //func是使用方式,不是注解。所以不能作用
        public void func() {
            System.out.printf("test func");
        }
    

    只能作用于注解类上。那么,元注解又有哪些类别,功能又有哪些哪?

    元注解分类
    • Documented 文档注解表明它被 javadoc或相似工具记录,生成各种文档。
    • @Target 用来约束注解用于范围(如方法、类或字段)。详细的作用范围有哪些,见 enum ElementType
    • @Inherited:某个被标注的类型是被继承的。即注解类型自动从父类继承,父类,但不会从接口继承。
    • @Retention用来约束注解的生命周期,分别有三个值,源码级别(source),类文件级别(class)或者运行时级别(runtime)。
      1. SOURCE:注解将被编译器丢弃(该类型的注解信息只会保留在源码里,源码经过编译后,注解信息会被丢弃,不会保留在编译好的class文件里)
      2. CLASS:注解在class文件中可用,但会被VM丢弃(该类型的注解信息会保留在源码里和class文件里,在执行的时候,不会加载到虚拟机中),请注意,当注解未定义Retention值时,默认值是CLASS,如Java内置注解,@Override、@Deprecated、@SuppressWarnning等
      3. RUNTIME:注解信息将在运行期(JVM)也保留,因此可以通过反射机制读取注解的信息(源码、class文件和执行的时候都有注解的信息),如SpringMvc中的@Controller、@Autowired、@RequestMapping等。
    • @Repeatable 描述标记的注解可重复注解的。

    有限的元注解涵盖了文档、代码编译、运行时标注等功能。实际上,它量不大,功能却是大千世界。

    自定义注解类

    程序猿毛病之一:喜欢自己DIY,什么都要自己练练。我也要手动写注解类。
    下面代码包括:变量的自定义注解、和方法的自定义注解,以及通过代码如何读取到注解内容。

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface FieldAnnotation {
    
        String value() default "call test annotation";
    }
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MethodAnnotation {
        String value() default "MethodAnnotation";
    }
    

    代码:把自定义注解分别用在函数和变量上

    public class TestSelfAnnotation {
    
        @MethodAnnotation(value="TestSelfAnnotation MethodAnnotation")
        public void printAnnotation() {
            System.out.printf("function printAnnotation");
        }
        @FieldAnnotation(value="TestSelfAnnotation field")
        Integer testVar = 0;
    /*     void  main(String [] args) {
            TestSelfAnnotation a = new TestSelfAnnotation();
            FieldAnnotation b = a.getClass().getAnnotation(FieldAnnotation.class);
            System.out.printf(b.value());
        }*/
    
    } 
    
    测试用例,获取注解类
      val a = new TestSelfAnnotation //定义类
       a.printAnnotation() //调用函数
       val b = a.getClass //获取类class
       val anno = b.getDeclaredMethods
       if(anno == null) println("anno is null") else println(s"anno not null ${anno.getClass.getName}")
        for(mt <- anno) { //!!!!! 同一个方法中可以有多个注解类,所以需要指定注解,才能获取值
          println(mt.getAnnotation(classOf[MethodAnnotation]).value())
        }
    
       val filed = b.getDeclaredField("testVar") //设定获取 testVar变量的注解
       println(filed.getAnnotation(classOf[FieldAnnotation]).value()) // classOf需要指定注解类类型是 FieldAnnotation,而不是声明TestSelfAnnotation 
    
    function printAnnotation
    anno not null ....
    TestSelfAnnotation MethodAnnotation //不同注解作用对象不同
    TestSelfAnnotation field
    

    后续

    文章是对java注解的入门介绍,接着自定义注解的例子。建立了解注解类的信心,为后续的使用注解对单体架构进行微服务化改造开个好头。

    有帮助的话,留个赞呗。没有的话,留个赞鼓励下。_

    相关文章

      网友评论

          本文标题:Java注解类 - 注解类入门

          本文链接:https://www.haomeiwen.com/subject/qrfmkctx.html