Одной из опций является процессор аннотаций . Например, если у вас есть следующая аннотация:
package com.example;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME) // must be at least SOURCE
@Target(ElementType.FIELD)
public @interface Foo {}
, то следующее будет выдавать ошибку, если в поле final
присутствует @Foo
:
package com.example;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;
import java.util.Set;
@SupportedAnnotationTypes("com.example.Foo")
@SupportedSourceVersion(SourceVersion.RELEASE_13) // or whatever version you support
public class FooProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (!annotations.isEmpty()) {
// This processor is only declared to process one annotation
TypeElement foo = annotations.iterator().next();
for (Element element : roundEnv.getElementsAnnotatedWith(foo)) {
for (AnnotationMirror mirror : element.getAnnotationMirrors()) {
if (mirror.getAnnotationType().asElement().equals(foo)
&& element.getModifiers().contains(Modifier.FINAL)) {
// processingEnv is a protected field of AbstractProcessor
processingEnv.getMessager()
.printMessage(Kind.ERROR, "Field cannot be final.", element, mirror);
break;
}
}
}
}
return true;
}
}
ВПриведенный выше код Я использовал только API модели (например, TypeElement
) для ссылки на аннотацию Foo
. Обратите внимание, однако, что API процессора аннотаций позволяет использовать класс аннотации (например, Foo.class
), если аннотация видима (т. Е. Ваш процессор зависит от аннотации). Использование API класса может быть более простым в использовании, более легким для размышления и более легким для чтения - используйте его, если ваш класс аннотаций видим для вашего класса процессора.
Затем вам нужно будет сказать javac
использовать процессор аннотаций. См. спецификацию инструмента для получения дополнительной информации;в частности, обратите внимание на стандартные опции --processor-path
, --processor-module-path
, -processor
и -proc
, а также раздел по обработке аннотаций.
Обратите внимание, что вы не сможетедля обеспечения использования вашего процессора аннотаций.