注解入门

620次阅读  |  发布于4年以前

介绍

jdk1.5之后Java增加了对元数据(MetaData)的支持,也就是Annotation(注解),他是代码里的特殊标记, 这些标记可以在编译,类加载,运行时被读取,并执行相应操作。通过使用注解可以在不改变原有逻辑的情况下, 在源文件中添加补充信息,代码分析工具,开发工具,部署工具,可以更具这些信息进行验证和部署。 Annotation就像Java修饰符一样,可以用于修饰包、类、构造器、方法、变量、参数、局部变量,这些信息 存储在Annotation的"name=value“中。 Annotation对程序的运行无影响,如果希望Annotation在运行时其到作用,就需要通过配套工具对 annotation中的信息进行访问处理,这一工具统称为APT。

基本的Annotation

java5为我们提供了基本的Annotation,使用时在前面加上@,

   /**         * 最常用的,限定重写父类方法,
         * 他在使用中我们感觉不到,主要是他作用是告诉编译器检查这个方法
         * 保证父类包含一个被该方法重写的方法,否则编译出错,避免程序员低级错误。
         */
        @Override

        /**
         * 标记过时
         * 标记类,方法等已过时,使用过时类、方法时编译器会发出警告
         */
        @Deprecated

        /**
         * 抑制编译警告
         * 有时程序编译会发出警告,但这时程序仍可正常运行,我们取消警告时使用。
         */
        @SuppressWarnings(value = "unchecked")

        /**
         * 堆污染 Java7出现
         * 在泛型的使用中有时会发生堆污染
         */
        @SafeVarargs

        /**
         * 函数式接口 Java8出现
         * 用该注解标记的接口必须是函数式接口
         */
        @FunctionalInterface

jdk的元Annotation

jdk除了除了五种基本的annotation外,在java.lang.annotation包下提供了6个Meta Annotation(元 annotation),其中5个都是用来修饰其他Annotation的,

1.@Retention 只能修饰annotation,用来指定修饰的Annotation可以保留多长时间。它包含一个RetentionPolicy类型 使用该注解时,必须指定该类型值,类型值包含

@Retention(value = RetentionPolicy.RUNTIME)
 public @interface Testable{}

2.@Target 也是只能修饰一个Annotation的定义,它用于指定被修饰的Annotation能用于修饰那些程序单元,@Target 也包含一个名为value的成员,该成员值如下

@Target(ElementType.FIELD)    
public @interface ActionListenerFor{}

3.@Documented 用于指定该元annotation修饰的annotation类将被Javadoc工具提取成文档,就是你定义的注解有@Documented 修饰,在自动提取API文档时,文档的方法会带有这个注解 4.@Inherited 该元annotation指定被它修饰的annotation将具有继承性,例如使用该元注解自定义的annotation,在修饰 了一个类后,该类的子类则默认使用你自定义的注解

//自定义注解

@Inherited
public @interface Inheritable{}

//使用自定义注解

@Inheritable
class Base{}

//检测子类是否带有注解

public class MyBase extends Base{
    public static void main(String [] args){
        //利用发射,来检查是否有注解,输出:true
    System.out.println(MyBase.class.isAnnotationPresent(Inheritable.class));
    }
}

自定义注解

自定义注解使用关键字 @interface,定义一个新的annotation类型与定义一个接口非常像,自定义注解后 就可以在任何地方使用了,

//自定义注解public @interface Test{}

自定义注解的成员变量

自定义注解的成员变量以无形参的方法形式来声明,其方法名和返回值定义该成员变量的名字和类型, 还可以为注解的成员变量设置默认值,以方法名后 default关键字 后在变量的值实现,

public @interface Test{    //定义String 类型的name成员变量,默认值为 “tian"
    String name() default "tian";
    int age() default 2 ;
}

//使用

@Test(name = "song", age = 12)
public class Person{}

提取Annotation信息

提取annotation信息需要了解Java反射的使用,annotation也是是类/类成员的一种属性,通过反射我们 可以得到annotation的信息,在利用这些信息进行进一步的操作。

/**
* 注意使用Retention,只有指定Retention为RetentionPolicy.RUNTIME
* 时在运行时才能获得注解信息
*/
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Test {
    String name() default "tian";
    int age() default 12;
}

//使用自定义注解

@Test(name = "song", age = 27)
public class Person {
}

//利用反射获取注解信息

public static void main(String[] args) {
    Annotation[] annotations = Person.class.getAnnotations();
    for (Annotation annotation : annotations) {
        if (annotation instanceof Test) {
            log(((Test) annotation).name());
        }
    }
}

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8