Zona J

Zona J header image 2

Annotations - interfaces "diferentes"

19 de Março de 2007 às 13:22 por Ruben Badaró · 1 Comentário ·

Numa discussão com um amigo, surgiu o tema sobre como classificar uma annotation. Será um interface ou uma classe, visto que embora seja definido com @ interface, podemos atribuir e retirar valores da annotation, indiciando que existe uma implementação dos métodos.


Na realidade, uma annotation é um tipo de interface. Tal como todas as classes que criamos extendem implícitamente a classe Object, sempre que criamos uma annotation esta extende implícitamente o interface Annotation. O interface annotation tem a seguinte definição:

public interface Annotation {
    boolean equals(Object obj);
    int hashpre();
    String toString();
    Class annotationType();
}

Se quisermos criar uma nova annotation, podemos declará-la da seguinte forma:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @ interface Teste{
    String umMembro();
}

Definimos uma annotation de teste com um membro do tipo String. Definimos com a Retention que a annotation vai estar disponível em runtime, e definimos no target que esta annotation pode ser utilizada em métodos. Utilizaríamos a annotation, por exemplo, neste simples bloco de código:

public class AnnotationsTest {

    @Teste(umMembro="textoMembro")
    public void umMetodo() {}
}

Estamos então a anotar o nosso método com a anotação que criámos anteriormente, e a definir uma propriedade exemplo. A primeira questão a reparar é que a annotation é um interface mas estamos a atribuir-lhe valores quando utilizamos a annotation, e podemos consultar as annotations definidas em run-time (porque colocámos retention = RUNTIME na definição da annotation). Podemos simplesmente, adicionar um método main a esta nossa classe AnnotationsTest para tentar perceber um pouco melhor o que acontece.

public static void main(String[] args) throws NoSuchMethodException {<
    AnnotationsTest at = new AnnotationsTest();
    Annotation[] annots = at.getClass().getMethod("umMetodo").getAnnotations();
    for(Annotation annot : annots) {
        System.out.println("Annotation? " + annot.annotationType().isAnnotation());
        System.out.println("Interface? " + annot.annotationType().isInterface());
        System.out.println("Nome da classe da annotation: " + annot.getClass());
        System.out.println("Nome do tipo da annotation: " + annot.annotationType().toString());
        Teste t = (Teste) annot;
        System.out.println("Valor do umMembro: " + t.umMembro());
    }
}

Na linha 3, vamos buscar todas as annotations do método umMetodo(). Isto é possível, porque com a introdução das annotations no Java 5, todos os elementos sobre os quais podemos aplicar anotações passaram a implementar o interface AnnotatedElement, que fornece um modo de se aceder às annotations numa classe, método, variável, parametro ou mesmo package. Depois percorremos a anotações e fazemos uns testes para ver o que nos diz sobre o que é uma anotação. O output é o seguinte:

Annotation? true
Interface? true
Nome da classe da annotation: class $Proxy3
Nome do tipo da annotation: interface zonaj.testes.annotations.Teste
Valor do umMembro: textoMembro

As primeiras duas linhas confirma-se o que já se sabia, a Annotation é um interface. Na terceira linha vem a explicação para as nossas dúvidas: a classe da anotação é um $Proxy3, nitidamente um proxy gerado pelo compilador em run-time. Este proxy é que implementa automáticamente os métodos para as propriedades definidadas na nossa anotação, bem como os métodos do interface Annotation.

Nas duas outras linhas de output, vemos que o annotationType é o Teste que criámos e vemos como obter o valor indicado na anotação do método.

Este método de geração de proxies não é muito explicado mas funciona aproximadamente como o Annotation Processing Tool (apt) que é uma aplicação que nos permite criar factories para gerar proxies e processar anotações.

De resto, uma anotação não é uma classe, é um interface. Só é criado um proxy automaticamente para poder ser utilizada.

Tags: java

1 resposta até ao momento ↓

  • Alex // Dez 19, 2007 at 2:09

    Parabêns! Gostei das explicações.
    Mais de um modo conclusivo quais as vantagens de utilizar annotations?

Deixe um comentário

XHTML: Pode usar estas tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>