Java注解梳理及自定义注解的使用

Java注解梳理及自定义注解的使用

  •  10个月前
  •  725
  •  Java 

什么是注解

Annontation是Java5开始引入的新特征,中文名称叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且供指定的工具或框架使用。Annontation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。

注解的作用

  • 提供信息给编译器: 编译器可以利用注解来探测错误和警告信息。
  • 编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。
  • 运行时的处理: 某些注解可以在程序运行的时候接受代码的提取,值得注意的是,注解不是代码本身的一部分。

元注解

元注解是可以注解到注解上的注解,或者说元注解是一种基本注解,但是它能够应用到其它的注解上面。现有@Target、@Retention、@Documented、@Inherited、@Repeatable5种元注解,其中@Repeatable是java8开始引入的。

@Target

@Target指定了注解修饰的范围。

// 可以修饰类型(类、接口、枚举) 
ElementType.TYPE

// 可以修饰属性 
ElementType.FIELD  

// 可以修饰方法 
ElementType.METHOD  

// 可以修饰方法内的参数 
ElementType.PARAMETER  

// 可以修饰构造方法 
ElementType.CONSTRUCTOR  

// 可以修饰注解 
ElementType.ANNOTATION_TYPE  

// 可以修饰局部变量 
ElementType.LOCAL_VARIABLE  

// 可以修饰包 
ElementType.PACKAGE  

// @since1.8  表示该注解能使用在自定义类型参数(参数的自定义类型可以是javaBean或者枚举等)的声明语句中 
TYPE_PARAMETER  

// @since1.8  表示该注解能使用在使用类型的任意语句中 
TYPE_USE

@Retention

@Retention制定了该注解被保留的时间长短。

// 在源文件中有效 
RetentionPolicy.SOURCE  

// 在class文件中有效 
RetentionPolicy.CLASS  

// 在运行时有效 
RetentionPolicy.RUNTIME

@Documented

@Documented是标记注解,标识将注解信息添加在文档中。

@Inherited

@Inherited也是一个标记注解,它阐述了某个被标注的类型是可被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

@Repeatable

@Repeatable注解表明标记的注解可以多次应用于相同的声明或类型。@since1.8

自定义注解

// 一个简单的自定义注解 @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface AnnotationName {     String value() detault ""; }

编写自定义注解需要注意:

  • Annotation型定义为@interface,所有的Annotation会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或接口。
  • 参数成员只能用public或default这两个访问权修饰。
  • 参数成员只能用基本数据类型byte、short、char、int、long、float、double、boolean八种基本数据类型和String、Enum、Class、Annotations等数据类型以及以上所有类型的数组。
  • 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取Annotation对象,因为你除此之外没有别的获取注解对象的方法。
  • 注解元素必须有确定的值。要么指定时给默认值,要么使用时给值。不过有时候我们需要确定表达一个元素不存在值,所以使用空字符串或者负数表示。

自定义注解的使用

创建注解

import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target;  

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface Description {      
    String value();  
}

创建注解的使用类

import java.lang.reflect.Field; import java.lang.reflect.Method;  

@Description("我是类") 
public class Test {      
    @Description("我是属性")     
    String field;      

    @Description("我是方法")     
    public void method() { }  }

测试

public static void main(String[] args) {      
    Class<Test> clazz = Test.class;      
    // class     
    if (clazz.isAnnotationPresent(Description.class)) {         
        Description classDesc = clazz.getAnnotation(Description.class);         
        System.out.println(classDesc.value());     
    }     
    // field     
    Field[] fields = clazz.getDeclaredFields();     
    for (Field field : fields) {         
        if (field.isAnnotationPresent(Description.class)) {             
            Description fieldDesc = field.getAnnotation(Description.class);             
            System.out.println(fieldDesc.value());         
        }     
    }     
    // method     
    Method[] methods = clazz.getDeclaredMethods();     
    for (Method method : methods) {         
        if (method.isAnnotationPresent(Description.class)) {             
            Description methodDesc = method.getAnnotation(Description.class);             
            System.out.println(methodDesc.value());         
        }     
    }  
}

输出结果为:

我是类 我是属性 我是方法


扫一扫分享到微信

已有 条评论
写评论