![]() |
![]() ![]() Annotations
![]() Por Arthur Silva Freire(arthur.freire@ccc.ufcg.edu.br)
Neste mês, a Coluna Java abordará um recurso que foi introduzido como padrão de linguagem na versão 1.5. Estamos falando de Annotations. Saiba o que é, pra que serve e como criar sua própria Annotation.
Você sabe o que são Annotations? Adivinha... são anotações. É um artifício que você tem para fazer alguma marcação em atributo, método, classe, entre outros. Dessa forma, podemos evitar, em muitos casos, arquivos XML de configuração, que tornam difícil a compreensão de alguns sistemas. Elas devem ser sempre declaradas antes do objeto que você quer anotar e uma @ (arroba) deve preceder o nome da sua anotação. Veja um exemplo simples abaixo . @MinhaAnotacao class MinhaClasse { }Nesta matéria, mostraremos dois exemplos para o uso de Annotations. Vamos ao primeiro. Todos nós sabemos que uma fase importante no desenvolvimento de software é a de testes. Você pode definir que todos os métodos que tiverem a anotação “@Testar” serão testados. Vamos agora criar essa anotação. Testar.java@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Testar { } //Observem que a nossa anotação deve ser anotada com meta-anotações. //A anotação @Retention(RetentionPolicy.RUNTIME) diz que a VM deve manter //essas anotações em tempo de execução para que sejam lidas a partir da reflexão. //Outras opções seriam: SOURCE e CLASS. //E a anotação @Target(ElementType.METHOD) indica que a nossa anotação só é //aplicada a métodos. Outras opções seriam: FIELD, TYPE (classe e interface), //PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, e PACKAGE.Pronto, criamos a nossa anotação. Agora, criaremos uma classe que será testada. ClasseParaTestar.javapublic class ClasseParaTestar { //Como o propósito é só demonstrar as anotações, os métodos não fazem nada. @Testar public void metodo1() { throw new RuntimeException("Deu zebra!"); } @Testar public void metodo2() { } @Testar public void metodo3() { } public void metodo4() { } @Testar public void metodo5() { throw new RuntimeException("Ixi maria... Erro!"); } public void metodo6() { } @Testar public void metodo7() { } public void metodo8() { } }Agora que nossos métodos já estão anotados, vamos criar a classe principal do nosso framework de testes. Testador.javapublic class Testador { public static void testar(Object obj) { Class> classe = obj.getClass(); int passou = 0; int falhou = 0; System.out.println("-------------Inicio dos Testes--------------"); for (Method m : classe.getDeclaredMethods()) { if (m.isAnnotationPresent(Testar.class)) { try { System.out.print("Testando o método: "; + m.getName()); m.invoke(obj); passou++; System.out.println(" => passou!"); } catch (Throwable t) { falhou++; System.out.println(" => falhou! " + t.getCause()); } } } System.out.println("---------------Fim dos Testes---------------"); System.out.println("Passaram: " + passou + ", Falharam: " + falhou); } }Para rodar, basta chamar o método estático passando um objeto da classe que você deseja testar. Testador.testar(new ClasseParaTestar());Esta será a saída para o primeiro exemplo: -------------Inicio dos Testes-------------- Testando o método: metodo1 =>; falhou! java.lang.RuntimeException: Deu zebra! Testando o método: metodo2 =>; passou! Testando o método: metodo3 =>; passou! Testando o método: metodo5 =>; falhou! java.lang.RuntimeException: Ixi maria... Erro! Testando o método: metodo7 =>; passou! ---------------Fim dos Testes--------------- Passaram: 3, Falharam: 2O nosso segundo exemplo consiste em criar uma anotação para validar os atributos. Vamos criar uma anotação para verificar se um atributo contém um determinado texto e outra para verificar se o atributo é positivo. ValidarPositivo.java@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ValidarPositivo { } ValidarContemTexto.java@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ValidarContemTexto { int min() default 1; } //As anotações podem conter atributos para realizar alguma lógica durante o processamento dessas. //No nosso caso, a anotação @ValidarContemTexto irá validar se o atributo que está //decorado com a anotação possui pelo menos min caracteres (que por default é 1). //Reparem que a meta-anotação @Target é ElementType.FIELD, porque vamos utilizar essas anotações //para decorar atributos.A nossa classe de testes será a seguinte: Usuario.javapublic class Usuario { @ValidarContemTexto(min = 10) private String login; @ValidarContemTexto(min = 20) private String senha; @ValidarPositivo private int nivel; //Construtores, getters e setters //... }Agora, a classe responsável pela validação: Validador.javapublic class Validador { public static boolean validar(Object obj) { Class> classe = obj.getClass(); boolean ok = true; for (Field f : classe.getDeclaredFields()) { f.setAccessible(true); //Annotation @ValidarPositivo if (f.isAnnotationPresent(ValidarPositivo.class)) { try { int num = Integer.parseInt(f.get(obj).toString()); if (num <= 0) { ok = false; throw new Exception(); } } catch (Throwable t) { System.out.println(f.getName() + " deve ser um valor inteiro positivo."); } } //Annotation @ValidarContemTexto if (f.isAnnotationPresent(ValidarContemTexto.class)) { ValidarContemTexto anotacao = f.getAnnotation(ValidarContemTexto.class); try { String texto = f.get(obj).toString(); if (texto.length() < anotacao.min()) { ok = false; System.out.println(f.getName() + " deve possuir pelo menos " + anotacao.min() + " caracteres."); } } catch (Throwable t) { System.out.println(f.getName() + ": " + t.getCause()); } } } return ok; } }O código a seguir cria três usuários e executa a validação com cada um deles. ArrayListO resultado é este: Validando usuario: login login deve possuir pelo menos 10 caracteres. senha deve possuir pelo menos 20 caracteres. Corrija os erros. Validando usuario: arthur senha deve possuir pelo menos 20 caracteres. nivel deve ser um valor inteiro positivo. Corrija os erros. Validando usuario: juca Usuário OK.Isso é o que tínhamos pra mostrar nesta matéria, uma breve introdução a Annotations. Caso queira se aprofundar mais, acesse o link da documentação. Jornal PETNews - Edição: Jeymisson Oliveira - Revisão: Iago Araújo e Joseana Fechine
Grupo PET Computação UFCG, 2012. All rights reserved. |
![]() |