Java 编程思想--注解(二)

1.采用 apt 工具构建注解处理器
(1)申明注解

/**
 *  申明注解
 *  function : 将一个类中的 public 提取出来,抽象为一个接口。
 *  value :作为抽象出来接口的名称
 *  该接口用户类级别,在编译之前对源代码进行处理。
 */

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface ExtractInterface {

    String value();

}

(2)使用注解

/**
 * 使用Multiplier 注解,内部实现两个数相乘。
 */
@ExtractInterface(value = "IMultiplier")
public class Multiplier {

    public int multiplier(int x, int y) {
        int total = 0;
        for (int i = 0; i < x; i++) {
            total = add(total, y);
        }
        return total;
    }

    private int add(int x, int y) {
        return x + y;
    }

    public static void main(String[] args) {
        Multiplier m = new Multiplier();
        System.out.println("11 * 16 = " + m.multiplier(11, 16));
    }

}

(3)注解处理器

/**
 * 注解处理器
 *
 * 1.首先需要加入 apt-mirror-api-0.1.jar
 * 2.需要实现 AnnotationProcessor 接口
 * 3.所有的工作都在 process() 方法中,在分析一个类的时候,我们用 MethodDeclaration 类以及其上的 getModifier() 方法找到 public 方法且不包括 static方法,
 * 找到我们所需的方法后,就将其保存在一个 集合中,然后在一个java文件中创建接口。
 */

public class InterfaceExtractorProcessor implements AnnotationProcessor {

    private final AnnotationProcessorEnvironment env;

    public InterfaceExtractorProcessor(AnnotationProcessorEnvironment env) {
        this.env = env;
    }

    private ArrayList<MethodDeclaration> interfaceMethods = new ArrayList<MethodDeclaration>();

    public void process() {
        for (TypeDeclaration typeDecl : env.getSpecifiedTypeDeclarations()) {
            ExtractInterface annot = typeDecl.getAnnotation(ExtractInterface.class);
            if (annot == null) {
                break;
            }
            for (MethodDeclaration method : typeDecl.getMethods()) {
                if (method.getModifiers().contains(Modifier.PUBLIC) && !(method.getModifiers().contains(Modifier.STATIC))) {
                    interfaceMethods.add(method);
                }
            }

            if (interfaceMethods.size() > 0) {
                try {
                    PrintWriter writer = env.getFiler().createSourceFile(annot.value());
                    writer.println("package " + typeDecl.getPackage().getQualifiedName() + ";");
                    writer.println("public interface " + annot.value() + " {");
                    for (MethodDeclaration method : interfaceMethods) {
                        writer.print(" public ");
                        writer.print(method.getReturnType() + " ");
                        writer.print(method.getSimpleName() + " (");
                        int i = 0;
                        for (ParameterDeclaration param : method.getParameters()) {
                            writer.print(param.getType() + " " + param.getSimpleName());
                            if (++i < method.getParameters().size()) {
                                writer.print(", ");
                            }
                            writer.print(");");
                        }
                        writer.println("}");
                        writer.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

(4)处理 “注解处理器” 的工厂

/**
 * apt 工具需要一个工厂类来为其指明正确的处理器,然后才能调用处理器上的 process()方法。
 *
 */
public class InterfaceExtractorProcessorFactory implements AnnotationProcessorFactory {
    public Collection<String> supportedOptions() {
        return Collections.emptySet();
    }

    public Collection<String> supportedAnnotationTypes() {
        return Collections.singleton("com.daxiong.annotation.base.demo03.ExtractInterface");
    }

    public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration> set, AnnotationProcessorEnvironment annotationProcessorEnvironment) {
        return new InterfaceExtractorProcessor(annotationProcessorEnvironment);
    }
}

2.总结
(1)jdk自带的注解,处理文档,覆盖等。
(2)java 元注解,用于自定义注解之上,构建用户自己需要的注解。

如何构建

对编译后文件:java 反射机制。
对编译前资源文件:jdk apt 构建工具。

两种方式的区别,优缺点

3.模拟 Junit 的 @Test

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值