3 coisas que você não sabia sobre as anotações em Java
Quem desenvolve aplicações usando a linguagem Java quase certamente conhece as anotações.
Por exemplo, considere a classe de um serviço hipotético abaixo:
@NotThreadSafe
public class MeuServico {
...
}
À classe foi adicionada a anotação NotThreadSafe
.
Ela indica que o serviço não é "thread-safe".
Em outras palavras, não é seguro que threads distintas acessem o serviço simultaneamente.
É importante notar que, por si só, a anotação nada faz; apenas adiciona à classe a informação de que ela não é thread-safe.
Por outro lado, um framework, por exemplo, pode utilizar esta informação para, em tempo de execução, restringir ou sincronizar o acesso a este serviço.
Neste post falo sobre 3 coisas que talvez você não sabia sobre as anotações Java.
Bora lá.
1. Anotações são apenas modificadores
Sintaticamente falando, anotações são apenas modificadores.
Para entender considere o método toString
abaixo:
@Override
public final String toString() {
return "Anotações são apenas modificadores";
}
Saiba que, para o compilador Java, a anotação é apenas mais um modificador do método.
Então a forma seguinte também é valida:
public @Override final String toString() {
return "Anotações são apenas modificadores";
}
Ou, se preferir, esta outra:
public final @Override String toString() {
return "Anotações são apenas modificadores";
}
As três formas são equivalentes em termos de sintaxe.
Vale notar, no entanto, que a primeira forma é a recomendável. Principalmente quando a anotação refere-se ao método.
A terceira forma pode ser usada caso a anotação refira-se ao tipo de retorno do método.
Em resumo, prefira as formas idiomáticas da linguagem.
2. Anotações de tipo e nomes completos qualificados
No item anterior eu mencionei anotações de tipo. Não entrarei em detalhes sobre o que sejam as anotações de tipo, está fora do escopo deste post.
Basta saber que, no exemplo abaixo, as anotações Foo
e Bar
referem-se aos tipos e não ao campo.
public class Exemplo01 {
public @Foo String a;
public @Bar LocalDate b;
}
Em outras palavras, a anotação Foo
adiciona informação ao tipo String
e não ao atributo a
.
De modo similar, Bar
adiciona informação ao tipo LocalDate
e não ao atributo b
.
Suponha que, por um motivo qualquer, você tenha que se referir aos tipos por seus nomes completos qualificados. Isto é, por algum motivo, você tenha que escrever:
public class Exemplo02 {
public java.lang.String a;
public java.time.LocalDate b;
}
E agora você precisa anotar os dois tipos com Foo
e Bar
respectivamente.
Saiba que o exemplo seguinte não compila:
// erro de compilação!
public class Exemplo02 {
public @Foo java.lang.String a;
public @Bar java.time.LocalDate b;
}
Para corrigir o erro de compilação é necessário fazer:
public class Exemplo02 {
public java.lang.@Foo String a;
public java.time.@Bar LocalDate b;
}
Ou seja, a anotação vem imediatamente antes do nome simples do tipo.
Sabia dessa?
3. Anotações de tipo e arrays
Considere o campo a
da classe seguinte:
public class Exemplo01 {
public int[][] a;
}
O seu tipo é um "array de array de ints", correto?
Temos, então, três tipos:
-
int[][]
- array de array de ints -
int[]
- array de ints -
int
- ints
É possível, então, anotar cada um desses tipos individualmente.
public class Exemplo02 {
public @C int[][] a;
public int @A [][] b;
public int[] @B [] c;
}
Ou anotar dois dos tipos:
public class Exemplo03 {
public @C int @A [][] a;
public int @A [] @B [] b;
public @C int[] @B [] c;
}
Ou anotar os três tipos:
public class Exemplo04 {
public @C int @A [] @B [] a;
}
Mas qual tipo exatamente está sendo anotado? Em todos os exemplos:
-
anotação
A
anota o tipoint[][]
-
anotação
B
anota o tipoint[]
-
anotação
C
anota o tipoint
Até o próximo artigo
Por hoje é isto. Espero que tenha gostado.
O código para todos os exemplos pode ser encontrado no GitHub.
Se tiver comentários, dúvidas ou correções sobre este post, por favor, envie um email.