10.注解(Thinking in java学习十)

2020-04-16  本文已影响0人  Vinson武

基本概念

  1. 定义:注解(也称为元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。

  2. 注解在一定程度上是在把元数据和元代码文件结合在一起。通过使用注解,我们可以把这些元数据保存在Java源代码中,并利用annotation API为自己的注解构造处理工具。

  3. Java内置了三种定义在java.lang中的注解

另外还提供了==四种元注解==,专门负责新注解的创建。

@Targer


image.png

@Retention


image.png

基本语法

定义注解

@Targer(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UserCase{
   //注解元素
    public int id();
    public String desc() default "no desc"; //默认值
}

注解的定义看起来很像接口的定义,注解也将会编译成class文件。

注解的元素看起来就像接口的方法,唯一的区别是你可以为其指定默认值。

没有元素的注解称为标记注解。

注解使用

public class Test{
    @UserCase(id = 47, desc = "xxxx")
    public boolean testMet(String str){
        ...
        return true;
    }
}

注解的元素在使用时表现为名-值对的形式,并需要置于@UserCase声明之后的括号内。

编写注解处理器

注解元素

注解元素的类型有以下几种:

如果使用其他类型,编译器会报错。注意,也不能使用包装类型。

默认值限制

编译器对注解元素默认值要求较高

注解不支持继承,不能使用关键字extends来继承某个@interface。

实现处理器

一个简单的原始注解处理器

public class UseCaseTraker{
    public static void useCaseTrakers(List<Integer> useCases, Class<?>cl){
        for(Method m : cl.getDeclaredMethods()){
            UseCase uc = m.getAnnotation(UseCase.class);
            if(uc !=null){
                System.out.println(uc.id() + " " + uc.desc());
                useCase.remove(new Integer(uc.id()));
            }
        }
        for(int i:useCase){
            System.out.println("current case " + i);
        }
    }
    public static void main(String[] args){
        List<Integer>useCase = new ArrrayList<Integer>();
        Collections.addAll(useCase, 47, 48);
        trackUseCase(useCase, Test.class);
    }
}
//输出: 47 xxxx
//current case 48

getAnnotation(Class<A> annotationClass)获得注解

getDeclaredAnnotations()获得注解元素

Java自定义注解是通过运行时靠反射获取注解

处理器的写法有固定的套路,继承AbstractProcessor。

public class MyProcessor extends AbstractProcessor {
 
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
    //当我们编译程序时注解处理器工具会调用此方法并且提供实现ProcessingEnvironment接口的对象作为参数。
        super.init(processingEnv);
    }
 
    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> types = new LinkedHashSet<>();
        types.add(UserCase.class.getCanonicalName());//返回该注解处理器支持的注解集合
        return types;

    }
 
    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }
 
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        //处理注解
        return true;
    }
}

注册注解处理器


image.png

google提供了一个注册处理器的库

compile 'com.google.auto.service:auto-service:1.0-rc2'

一个注解搞定:

@AutoService(Processor.class)
public class MyProcessor extends AbstractProcessor {
      ...
}
上一篇下一篇

猜你喜欢

热点阅读