The Checker Framework - Sistemas de tipos conectáveis para Java
1. Visão geral
A partir do lançamento deJava 8, é possível compilar programas usando os chamadosPluggable Type Systems - que podem aplicar verificações mais rígidas do que as aplicadas pelo compilador.
Precisamos apenas usar as anotações fornecidas pelos váriosPluggable Type Systems disponíveis.
Neste artigo rápido, exploraremosthe Checker Framework, cortesia da Universidade de Washington.
2. Maven
Para começar a trabalhar com o Checker Framework, precisamos primeiro adicioná-lo ao nossopom.xml:
A última versão das bibliotecas pode ser verificada emMaven Central.
As duas primeiras dependências contêm o código deThe Checker Framework, enquanto a última é uma versão customizada das classesJava 8, em que todos os tipos foram anotados corretamente pelos desenvolvedores deThe Checker Framework.
Em seguida, temos que ajustar corretamente omaven-compiler-plugin para usarThe Checker Framework como umType System conectável:
O ponto principal aqui é o conteúdo da tag<annotationProcessors>. Aqui listamos todas as peças que queremos executar contra nossas fontes.
3. Evitando NullPointerExceptions
O primeiro cenário em queThe Checker Framework pode nos ajudar é identificar a parte dos códigos onde umNullPoinerException poderia se originar:
private static int countArgs(@NonNull String[] args) {
return args.length;
}
public static void main(@Nullable String[] args) {
System.out.println(countArgs(args));
}
No exemplo acima, declaramos com a anotação@NonNull que o argumentoargs decountArgs() não deve ser nulo.
Independentemente dessa restrição, emmain(), invocamos o método passando um argumento que pode de fato ser nulo, porque foi anotado com@Nullable.
Quando compilamos o código,The Checker Framework nos avisa devidamente que algo em nosso código pode estar errado:
[WARNING] /checker-plugin/.../NonNullExample.java:[12,38] [argument.type.incompatible]
incompatible types in argument.
found : null
required: @Initialized @NonNull String @Initialized @NonNull []
4. Uso adequado de constantes como enumerações
Às vezes, usamos uma série de constantes como itens de uma enumeração.
Vamos supor que precisamos de uma série de países e planetas. Podemos então anotar esses itens com a anotação@Fenum para agrupar todas as constantes que fazem parte da mesma enumeração “falsa”:
static final @Fenum("country") String ITALY = "IT";
static final @Fenum("country") String US = "US";
static final @Fenum("country") String UNITED_KINGDOM = "UK";
static final @Fenum("planet") String MARS = "Mars";
static final @Fenum("planet") String EARTH = "Earth";
static final @Fenum("planet") String VENUS = "Venus";
Depois disso, quando escrevemos um método que deve aceitar uma String que é um "planeta", podemos anotar adequadamente o argumento:
Este é obviamente um erro potencial porque a expressão regular atribuída aFIND_NUMBERS não possui nenhum grupo correspondente.
Na verdade,the Checker Framework nos informará diligentemente sobre nosso erro em tempo de compilação:
[WARNING] /checker-plugin/.../RegexExample.java:[7,51] [assignment.type.incompatible]
incompatible types in assignment.
found : @Regex String
required: @Regex(1) String
6. Conclusão
The Checker Framework é uma ferramenta útil para desenvolvedores que desejam ir além do compilador padrão e melhorar a exatidão de seu código.
É capaz de detectar, em tempo de compilação, vários erros típicos que geralmente só podem ser detectados em tempo de execução ou até mesmo interromper a compilação, levantando um erro de compilação
Existem muito mais verificações padrão do que abordamos neste artigo; verifique os cheques disponíveis no manual oficialThe Checker Frameworkhere, ou mesmo escreva o seu próprio.
Como sempre, o código-fonte deste tutorial, com mais alguns exemplos, pode ser encontradoover on GitHub.