zoukankan      html  css  js  c++  java
  • Java基础—注解

    一、是什么
    看到一句很牛逼也很能拿出来装逼的话:比较糟糕的技术文档主要特征之一就是——用专业名词来介绍专业名词。用这句话来解释官方文档对注解的解释很恰当:Java 注解用于为 Java 代码提供元数据。
    Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。
    敲黑板划重点:Annotation是被动的元数据,永远不会有主动行为。注解主要给编译器及工具类型的软件用的。所以但凡Annotation起作用的场合都是有一个执行机制/调用者通过反射获得了这个元数据然后根据它采取行动。翻JUnit的代码一定能找到它去查询被调用的class有没有某某Annotation,然后如果有就怎么怎么样的代码。
    注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象$Proxy1。通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池。
     
    注解分类:
    元注解:注解其他注解的注解就叫元注解,一般在定义注解的时候用到元注解。
    @Retention– 定义该注解的生命周期。
    SOURCE源码注解:只在源码中存在,编译成.class文件就不存在了。
    CLASS编译时注解:在源码和.class文件中都存在。
    RUNTIME运行时注解:在运行阶段还起作用,甚至会影响运行逻辑的注解。可以通过反射获取
     
    @Target –注解用于什么地方。
    CONSTRUCTOR(构造方法声明),FIELD(字段声明),LOCAL VARIABLE(局部变量声明),METHOD(方法声明),PACKAGE(包声明),PARAMETER(参数声明),TYPE(类接口)
     
    @Inherited – 是否允许子类继承该注解。
    @Documented –注解是否将包含在JavaDoc中。
    @Repeatable –同一个位置重复相同的注解
     
    Java标准注解:
    @Overrid:它被用作标注方法。它说明了被标注的方法重载了父类的方法,起到了断言的作用。
    @Deprecated:当一个类型或者类型成员使用@Deprecated修饰的话,编译器将不鼓励使用这个被标注的程序元素。
    @SuppressWarnings:它有一个类型为String[]的成员,这个成员的值为被禁止的警告名。
     
    第三方注解及自定义注解:
    Spring注解:
    @Controller;@RequestMapping;@Resource;@ResponseBody;@RequestParam;@Service;@Autowired;@Override;@Component;@JoinTable;@Transational;@Param;@syschronized
    MyBatis注解:
    @CacheNamespace:为给定的命名空间(比如类)配置缓存。
    @Result:在列和属性或字段之间的单独结果映射。
    @Options:这个注解提供访问交换和配置选项的宽广范围,它们通常在映射语句上作为属性出现。而不是将每条语句注解变复杂,Options注解提供连贯清晰的方式来访问它们。
    @Insert
    @Update
    @Delete
    @Select
     
    注解元素的数据类型:
    注解的数据类型:所有基本类型(int,float,boolean,byte,double,char,long,short);String;Class;enum;Annotation;前面类型的数组
    编译器对元素的默认值有限制。首先,元素不能有不确定的值。也就是说,元素必须要么具有默认值,要么在使用注解时提供元素的值。其次,对于非基本类型的元素,无论是在源代码中声明,还是在注解接口中定义默认值,都不能以null作为值。
     
    二、有什么用
    2、跟踪代码依赖性,实现替代配置文件功能。比如Dagger 2依赖注入,未来java开发,将大量注解配置,具有很大用处;
    3、在编译时进行格式检查。如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。
    4、提供信息给编译器: 编译器可以利用注解来探测错误和警告信息
    5、编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。
    6、运行时的处理: 某些注解可以在程序运行的时候接受代码的提取
     
    三、怎么用
    1、注解的定义
    注解通过 @interface 关键字进行定义。
    public @interface TestAnnotation {
    }
    它的形式跟接口很类似,不过前面多了一个 @ 符号。上面的代码就创建了一个名字为 TestAnnotaion 的注解。
     
    2、注解的属性
    注解的属性也叫做成员变量。注解只有成员变量,没有方法。注解的成员变量在注解的定义中以“无形参的方法”形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。
    int id();String msg();
     
    3、注解的应用
    创建一个类 Test,然后在类定义的地方加上 @TestAnnotation 就可以用 TestAnnotation 注解这个类了。
     
    4、注解的解析
    注解通过反射获取。
    通过 Class 对象的 isAnnotationPresent() 方法判断它是否应用了某个注解。
    通过 getAnnotation() 方法来获取 Annotation 对象。
    通过getAnnotations() 方法获取所有Annotation对象。
    如果获取到的 Annotation 如果不为 null,则就可以调用它们的属性方法了。
     
    Java在java.lang.reflect 反射包下新增了AnnotatedElement接口,它主要用于表示目前正在 VM 中运行的程序中已使用注解的元素,通过该接口提供的方法可以利用反射技术地读取注解的信息,如反射包的Constructor类、Field类、Method类、Package类和Class类都实现了AnnotatedElement接口。
     
    四、深入研究方向
    1、自定义注解的作用和应用场景
    类属性自动赋值
    验证对象属性完整性
    跟踪代码的依赖性
    代替配置文件功能,像spring基于注解的配置
    可以生成文档,像java代码注释中的@see,@param等
     
    五、面试点
    注解的缺点:
    注解的提取需要借助于 Java 的反射技术,反射比较慢,所以注解使用时也需要谨慎计较时间成本。
     

  • 相关阅读:
    Python内置函数(67)——zip
    Python内置函数(66)——vars
    Python内置函数(65)——type
    Python内置函数(64)——tuple
    Python内置函数(63)——super
    Python内置函数(62)——sum
    Python内置函数(61)——str
    Python内置函数(60)——staticmethod
    Hadoop初体验(续)--YARN
    Hadoop初体验
  • 原文地址:https://www.cnblogs.com/qhj348770376/p/9377789.html
Copyright © 2011-2022 走看看