La prevención de la anotación de Java que se añade a campo final

Istvan Devai:
@MyAnnotation
final Integer value;

¿Es posible configurar un MyAnnotation anotación personalizada de una manera que hará que un error de tiempo de compilación anterior, pero no hay error en tiempo de compilación cuando se añade a un campo no final? (Independientemente de su nivel de acceso).

información de fondo: en nuestro código, tenemos una anotación especial que disparadores Modificación de a través de la reflexión de una clase fuera y esto no se puede hacer para los campos finales, por lo que nos gustaría advertir a los usuarios de la anotación en tiempo de compilación (en la actualidad tenemos un tiempo de ejecución comprobar que lanzar una excepción).

repollo:

Una opción es un procesador de anotación . Por ejemplo, si usted tiene la siguiente anotación:

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 {}

Entonces el siguiente emitirá un error si @Fooestá presente en un finalcampo:

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;
  }
}

En el código anterior sólo se utiliza la API de modelo (por ejemplo TypeElement) para hacer referencia a la Fooanotación. Nótese, sin embargo, que la API procesador de anotación sí permite que se debe usar la clase de la anotación (por ejemplo Foo.class) si la anotación es visible (es decir, el procesador tiene una dependencia en la anotación). Utilizando el API de la clase puede ser más fácil de usar, fácil de razonar sobre, y más fácil de leer a utilizarlo si su clase de anotación es visible a su clase de procesador.


A continuación, tendría que decirle javaca utilizar el procesador de anotación. Ver la especificación de herramientas para obtener más información; Específicamente, mira los --processor-path, --processor-module-path, -processor, y -procopciones estándar, así como la sección de procesamiento de anotación.

Nota Es posible que no sea capaz de imponer el uso de su procesador de anotación.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=330897&siteId=1
Recomendado
Clasificación