Java注解简述

        注解也称元数据,是JDK5之后引入的新特性,定义在java.lang中的内置注解主要有:@Override、@Deprecated、@SuppressWarning等。Java还提供另外四种注解,用于自定义新的注解。注解可以在程序运行期间发挥作用,也可以在编译期发挥作用(JDK6之后)。

        注解的定义与接口的定义相似,且除了编译器使用的注解(如@Override)外,其他注解也会被编译进class文件。定义注解时需要一些元注解,如@Target和@Retention。@Target用来定义注解将应用于什么地方(如用在类上、方法上、属性上等),@Retention用于定义注解的使用级别,共三种——源代码(SOURCE)、类文件(CLASS)、运行时(RUNTIME)。三者的区别我在知乎找到一个回答Java annotation 中 SOURCE 和 CLASS 的区别?

  • SOURCE:只在本编译单元的编译过程中保留,并不写入Class文件中。这种注解主要用于在本编译单元(这里一个Java源码文件可以看作一个编译单元)内触发注解处理器(annotation processor)的相关处理,例如说可以让注解处理器相应地生成一些代码,或者是让注解处理器做一些额外的类型检查,等等。
  • CLASS:在编译的过程中保留并且会写入Class文件中,但是JVM在加载类的时候不需要将其加载为运行时可见的(反射可见)的注解。这里很重要的一点是编译多个Java文件时的情况:假如要编译A.java源码文件和B.class文件,其中A类依赖B类,并且B类上有些注解希望让A.java编译时能看到,那么B.class里就必须要持有这些注解信息才行。同时我们可能不需要让它在运行时对反射可见(例如说为了减少运行时元数据的大小之类),所以会选择CLASS而不是RUNTIME。
  • RUNTIME:在编译过程中保留,会写入Class文件,并且JVM加载类的时候也会将其加载为反射可见的注解。这就不用多说了,例如说Spring的依赖注入就会在运行时通过扫描类上的注解来决定注入啥。

注解还可以包含一些元素以表示某些值,这些元素看起来就像接口的方法,如下示例

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    public string value() default "";
}

  自定义注解名为MyAnnotation,作用在方法上,运行期间可用,元素value的默认值为“”。

        该注解本身并不做任何事情,如果没用用来读取注解的工具,那注解也不会比注释更有用。因此还需要创建和使用注解处理器,注解处理器的编写通常会使用反射的API。JDK6还设计了一组被称为“插入式注解处理器”的标准API,可以提前至编译期对代码中的特定注解进行处理。可以把插入式注解处理器看作是一组编译器的插件,当这些插件工作时,允许读取、修改、添加抽象语法树中的任意元素,从而干预编译器的行为。譬如著名的提高编码效率的工具Lombok,它可以通过注解实现自动产生getter/setter方法、产生equals()和hashcode()等等,从而加快编码速度。

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值