Java注解(2)-自定义注解、注解处理器

1、如何定义一个注解

在自定注解前先看看java提供的@Override是如何定义的

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

通过元注解@Target(ElementType.METHOD)表明该注解可修饰方法,@Retention(RetentionPolicy.SOURCE)表明该注解只保留在源码中,编译器会忽略掉,不会出现在.class字节码文件中。

下面定义一个MyAnnotation,包含一个value属性,并且演示如何通过反射获取注解的信息。

自定义注解通过@interface关键字来定义,非常类似于接口的定义

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    //声明一个属性value,并设置默认值hello,在使用注解时没有指定值就会使用这个默认值
    String value() default "hello";
}

可以理解为方法的返回值类型就是属性的数据类型,方法名就是属性名。

2、提取注解信息

使用注解修饰某些程序元素之后,注解不会自己生效,必须由开发者提供相应的工具来读取并处理注解信息。从Java5开始,java.lang.reflect包反射API提供了读取运行时注解的能力。注意:只有定义注解时使用@Retention(RetentionPolicy.RUNTIME)修饰的的注解才能在运行时可见。

Java 5 在 java.lang.reflect包下新增了AnnotatedElement接口,这个接口的实现类主要包括

  • Class: 类定义
  • Constructor: 构造器定义
  • Field: 类的成员变量定义
  • Method: 方法的定义
  • Package: 包的定义

程序可调用AnnotatedElement接口下的方法来访问注解信息,这个接口包含如下方法(jdk 1.8)。

//判断该程序元素上是否存在指定的注解,如果存在返回true,否则返回false.
default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
        return getAnnotation(annotationClass) != null;
    }
//返回该程序元素上指定类型的注解,否则返回null
<T extends Annotation> T getAnnotation(Class<T> annotationClass);
//返回该程序元素上的注解数组,如果没有则返回一个长度为0的数组
Annotation[] getAnnotations();
//这个方法与<T extends Annotation> T getAnnotation(Class<T> annotationClass)的功能基本相似,但是java8增加了重复注解,因此需要使用该方法获取修饰该元素的指定类型的多个注解。

default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass)
//返回直接修饰该程序元素的注解数组,如果没有则返回长度为0的数组
Annotation[] getDeclaredAnnotations();
//返回直接修饰该程序元素的指定类型注解的数组,如果没有则返回长度为0的数组
default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass)
//该方法与default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass)基本相似,但是java8增加了重复注解,因此需要使用该方法获取修饰该元素的指定类型的多个注解。
default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass)

下面使用前面定义的MyAnnotation,并通过反射获取其value值

class Orange {

    @MyAnnotation(value="I am an orange...")
    public void info(){
        System.out.println("橙子");
    }
}
public class MyAnnotationTest {

    public static void main(String[] args) {
        try {
            Annotation[] ans = Class.forName("com.jdqm.annotation.test.Orange").getMethod("info").getAnnotations();
            for(Annotation an: ans) {
                System.out.println(((MyAnnotation)an).value());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

打印结果

I am an orange...

这个例子中我们在使用注解的时候设置了value的值为“I am an orange…”,如果不设置的话就是使用默认的hello。

原文地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值