Processadores de Anotações em Tempo de Compilação
Escreva um AbstractProcessor para gerar arquivos de código-fonte ou validar código em tempo de compilação.
Processadores de Anotações em Tempo de Compilação é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.
O que são processadores de anotações?
Os processadores de anotações (APT — Ferramenta de Processamento de Anotações) são executados durante a compilação. Eles inspecionam anotações do código-fonte e podem gerar novos arquivos de código-fonte, arquivos de recursos ou produzir erros e avisos do compilador.
AbstractProcessor: a classe base
Estenda javax.annotation.processing.AbstractProcessor. Substitua process() para processar elementos anotados. Declare as anotações compatíveis e a versão do código-fonte 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 */ }
}Registrando o processador
Registre o processador em META-INF/services/javax.annotation.processing.Processor com o nome completo da classe. As ferramentas de compilação (Maven, Gradle) o detectam automaticamente.
# META-INF/services/javax.annotation.processing.Processor
com.example.BuilderProcessorGerando arquivos de código-fonte
Use processingEnv.getFiler().createSourceFile() para gravar um novo arquivo .java. O compilador compila o arquivo gerado na mesma rodada (ou na próxima).
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");
}Inspecionando o modelo de elementos
Os processadores de anotações trabalham com elementos Element (não com Class — o código-fonte ainda não foi compilado). Use TypeElement, VariableElement e 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());Emitindo erros do compilador
Chame processingEnv.getMessager().printMessage() para emitir erros, avisos ou observações. É assim que anotações de restrição personalizadas sinalizam violações em tempo de compilação.
processingEnv.getMessager().printMessage(
Diagnostic.Kind.ERROR,
"@GenerateBuilder requires at least one field",
element
);Processamento em várias rodadas
O processamento de anotações ocorre em rodadas. Se você gerar um arquivo que contenha anotações, o processador poderá ser executado novamente na rodada seguinte. roundEnv.processingOver() sinaliza a rodada final.
if (roundEnv.processingOver()) {
// last round — write summary files or do cleanup
}Lombok por baixo dos panos
Lombok usa uma extensão APT não padrão que modifica a AST de classes existentes (algo não permitido pela especificação). Suas anotações, como @Data, @Builder e @Getter, geram métodos diretamente na classe compilada.
Geração de código com MapStruct
MapStruct gera implementações de mapeadores com segurança de tipos em tempo de compilação. Ele lê interfaces anotadas com @Mapper e grava implementações como classes Java comuns — sem reflexão em tempo de execução.
@Mapper
public interface UserMapper {
UserDto toDto(User user);
User toEntity(UserDto dto);
}
// MapStruct generates: UserMapperImpl.java at compile timeTestando processadores de anotações
Use google/compile-testing ou Kapt (para Kotlin) para testar processadores com testes unitários. Forneça textos de código-fonte e verifique os arquivos gerados ou os erros do 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");Empacotamento do processador
Empacote o processador em um módulo Maven separado. O módulo de anotações (somente anotações) é uma dependência de compile; o módulo do processador tem escopo annotationProcessor e nunca deve ser uma dependência em tempo de execução.
// build.gradle:
dependencies {
implementation "com.example:my-annotations:1.0"
annotationProcessor "com.example:my-processor:1.0"
}Verificação rápida
Onde você registra um processador de anotações para descoberta automática?
Recapitulação
Estenda AbstractProcessor, registre em META-INF/services, gere código-fonte com Filer e emita erros com Messager. Empacote os processadores separadamente. Use compile-testing para testes unitários. Isso elimina a sobrecarga da reflexão em tempo de execução.
Perguntas Frequentes
A aula “Processadores de Anotações em Tempo de Compilação” é grátis?
Sim — o texto completo de “Processadores de Anotações em Tempo de Compilação” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.
O que vou aprender em “Processadores de Anotações em Tempo de Compilação”?
Escreva um AbstractProcessor para gerar arquivos de código-fonte ou validar código em tempo de compilação. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Java Academy?
Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Processadores de Anotações em Tempo de Compilação”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Java Academy?
Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Definição de Anotações: Elementos e Valores Padrão
- Políticas de Retenção e Tipos de Destino
- Processamento de Anotações em Tempo de Execução
- Processadores de Anotações em Tempo de Compilação