在Java中,我考虑使用注解处理。apt工具会在实际解析源文件之前扫描源文件。
在编译源文件时,输出将被打印出来:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyInterface {
int offset() default 0;
int last() default 100;
}
处理器工厂:
public class MyInterfaceAnnotationProcessorFactory implements AnnotationProcessorFactory {
public Collection<String> supportedOptions() {
System.err.println("Called supportedOptions.............................");
return Collections.EMPTY_LIST;
}
public Collection<String> supportedAnnotationTypes() {
System.err.println("Called supportedAnnotationTypes...........................");
return Collections.singletonList("practiceproject.MyInterface");
}
public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration> set, AnnotationProcessorEnvironment ape) {
System.err.println("Called getProcessorFor................");
if (set.isEmpty()) {
return AnnotationProcessors.NO_OP;
}
return new MyInterfaceAnnotationProcessor(ape);
}
}
实际的注解处理器:
public class MyInterfaceAnnotationProcessor implements AnnotationProcessor {
private AnnotationProcessorEnvironment ape;
private AnnotationTypeDeclaration atd;
public MyInterfaceAnnotationProcessor(AnnotationProcessorEnvironment ape) {
this.ape = ape;
atd = (AnnotationTypeDeclaration) ape.getTypeDeclaration("practiceproject.MyInterface");
}
public void process() {
Collection<Declaration> decls = ape.getDeclarationsAnnotatedWith(atd);
for (Declaration dec : decls) {
processDeclaration(dec);
}
}
private void processDeclaration(Declaration d) {
Collection<AnnotationMirror> ams = d.getAnnotationMirrors();
for (AnnotationMirror am : ams) {
if (am.getAnnotationType().getDeclaration().equals(atd)) {
Map<AnnotationTypeElementDeclaration, AnnotationValue> values = am.getElementValues();
int offset = 0;
int last = 100;
for (Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue> entry : values.entrySet()) {
AnnotationTypeElementDeclaration ated = entry.getKey();
AnnotationValue v = entry.getValue();
String name = ated.getSimpleName();
if (name.equals("offset")) {
offset = ((Integer) v.getValue()).intValue();
} else if (name.equals("last")) {
last = ((Integer) v.getValue()).intValue();
}
}
System.err.println("Sum: " + ((last + 1 - offset) / 2) * (2 * offset + (last - offset)));
}
}
}
}
然后我们创建一个源文件。简单的类使用 MyInterface 注释:
@MyInterface(offset = 1, last = 1000)
public class Main {
@MyInterface
void doNothing() {
System.out.println("Doing nothing");
}
public static void main(String[] args) {
Main m = new Main();
m.doNothing();
MyInterface my = (MyInterface) m.getClass().getAnnotation(MyInterface.class);
System.out.println("offset: " + my.offset());
System.out.println("Last: " + my.last());
}
}
注解处理器被编译成一个jar文件,然后使用apt工具编译源文件,如下所示:
apt -cp "D:\Variance project\PracticeProject\dist\practiceproject.jar" -factory practiceproject.annotprocess.MyInterfaceAnnotationProcessorFactory "D:\Variance project\PracticeProject2\src\practiceproject2\Main.java"
该项目的输出结果为:
Called supportedAnnotationTypes...........................
Called getProcessorFor................
Sum: 5000
Sum: 500500
const int value = 1 + 2 + 3.... + 1000; Console.WriteLine(value);
这段代码的意思是:定义一个整型常量value,其值为从1加到1000的结果,然后使用Console.WriteLine方法将value输出到控制台。 - George Duckett