0Pricing
Java Academy · Lección

Procesadores de anotaciones en tiempo de compilación

Escriba un AbstractProcessor para generar archivos de código fuente o validar código en tiempo de compilación.

Procesadores de anotaciones en tiempo de compilación es una lección gratuita de Java Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Java Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Java Academy incluye 4 lecciones en total.

¿Qué son los procesadores de anotaciones?

Los procesadores de anotaciones (APT, Annotation Processing Tool) se ejecutan durante la compilación. Inspeccionan las anotaciones del código fuente y pueden generar archivos de código fuente, archivos de recursos o producir errores y advertencias del compilador.

AbstractProcessor: la clase base

Extienda javax.annotation.processing.AbstractProcessor. Reescriba process() para gestionar los elementos anotados. Declare las anotaciones compatibles y la versión del código fuente de Java.

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;

@SupportedAnnotationTypes("com.example.GenerateBuilder")
@SupportedSourceVersion(SourceVersion.RELEASE_17)
public class BuilderProcessor extends AbstractProcessor {
    @Override
    public boolean process(Set<? extends TypeElement> annotations,
                           RoundEnvironment roundEnv) {
        for (Element e : roundEnv.getElementsAnnotatedWith(GenerateBuilder.class)) {
            generateBuilder((TypeElement) e);
        }
        return true;
    }
    private void generateBuilder(TypeElement cls) { /* generate source */ }
}

Registrar el procesador

Registre el procesador en META-INF/services/javax.annotation.processing.Processor con el nombre de clase completo. Las herramientas de compilación (Maven, Gradle) lo detectan automáticamente.

# META-INF/services/javax.annotation.processing.Processor
com.example.BuilderProcessor

Generar archivos de código fuente

Utilice processingEnv.getFiler().createSourceFile() para escribir un archivo .java nuevo. El compilador compila después el archivo generado en la misma ronda (o en la siguiente).

JavaFileObject file = processingEnv.getFiler()
    .createSourceFile("com.example.UserBuilder");
try (Writer w = file.openWriter()) {
    w.write("package com.example;\n");
    w.write("public class UserBuilder {\n");
    w.write("  // generated builder\n");
    w.write("}\n");
}

Inspeccionar el modelo de elementos

Los procesadores de anotaciones trabajan con Elements (no con Classes, porque el código fuente aún no se ha compilado). Utilice TypeElement, VariableElement y ExecutableElement.

TypeElement classElement = (TypeElement) element;
String className = classElement.getSimpleName().toString();
List<VariableElement> fields = classElement.getEnclosedElements().stream()
    .filter(e -> e.getKind() == ElementKind.FIELD)
    .map(e -> (VariableElement) e)
    .collect(Collectors.toList());

Emitir errores del compilador

Llame a processingEnv.getMessager().printMessage() para emitir errores, advertencias o notas. Así es como las anotaciones de restricciones personalizadas señalan infracciones en tiempo de compilación.

processingEnv.getMessager().printMessage(
    Diagnostic.Kind.ERROR,
    "@GenerateBuilder requires at least one field",
    element
);

Procesamiento en varias rondas

El procesamiento de anotaciones se realiza en rondas. Si genera un archivo que contiene anotaciones, el procesador puede ejecutarse de nuevo en la ronda siguiente. roundEnv.processingOver() indica la ronda final.

if (roundEnv.processingOver()) {
    // last round — write summary files or do cleanup
}

Lombok internamente

Lombok utiliza una extensión APT no estándar que modifica el AST de las clases existentes (algo que la especificación no permite). Sus anotaciones, como @Data, @Builder y @Getter, generan métodos directamente en la clase compilada.

Generación de código con MapStruct

MapStruct genera implementaciones de mapeadores con seguridad de tipos en tiempo de compilación. Lee interfaces anotadas con @Mapper y escribe las implementaciones como clases Java normales, sin reflexión en tiempo de ejecución.

@Mapper
public interface UserMapper {
    UserDto toDto(User user);
    User toEntity(UserDto dto);
}
// MapStruct generates: UserMapperImpl.java at compile time

Probar procesadores de anotaciones

Utilice google/compile-testing o Kapt (para Kotlin) para probar los procesadores unitariamente. Proporcione cadenas de código fuente y compruebe los archivos generados o los errores del compilador.

JavaFileObject src = JavaFileObjects.forSourceString("Test",
    "@GenerateBuilder public class Test { private String name; }");
Compilation c = Compiler.javac().withProcessors(new BuilderProcessor()).compile(src);
CompilationSubject.assertThat(c).succeeded();
CompilationSubject.assertThat(c).generatedSourceFile("TestBuilder");

Empaquetar el procesador

Empaquete el procesador en un módulo de Maven independiente. El módulo de anotaciones (solo anotaciones) es una dependencia compile; el módulo del procesador utiliza el ámbito annotationProcessor y nunca debe ser una dependencia en tiempo de ejecución.

// build.gradle:
dependencies {
    implementation "com.example:my-annotations:1.0"
    annotationProcessor "com.example:my-processor:1.0"
}

Comprobación rápida

¿Dónde se registra un procesador de anotaciones para que se detecte automáticamente?

Recapitulación

Extienda AbstractProcessor, regístrelo en META-INF/services, genere código fuente con Filer y emita errores con Messager. Empaquete los procesadores por separado. Utilice compile-testing para las pruebas unitarias. Así se elimina la sobrecarga de la reflexión en tiempo de ejecución.

Preguntas frecuentes

¿La lección «Procesadores de anotaciones en tiempo de compilación» es gratis?

Sí — el texto completo de «Procesadores de anotaciones en tiempo de compilación» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Java Academy, actualiza a CoddyKit PRO. El curso de Java Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Procesadores de anotaciones en tiempo de compilación»?

Escriba un AbstractProcessor para generar archivos de código fuente o validar código en tiempo de compilación. Practicas Java Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Java Academy?

No se requiere experiencia previa. Java Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Procesadores de anotaciones en tiempo de compilación»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Java Academy?

Sí. Cada lección de Java Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Definición de anotaciones: elementos y valores predeterminados
  2. Políticas de retención y tipos de destino
  3. Procesamiento de anotaciones en tiempo de ejecución
  4. Procesadores de anotaciones en tiempo de compilación
← Volver a Java Academy