Estudo Sobre o Uso de Anotações em Java Fabricio C. Mota1 , Regis S. Onishi1 , Miguel D. Matrakas1 1 UDC ANGLO – Faculdade Anglo Americano (FAA) Av. Paraná, 5661, CEP: 85868-030 – Foz do Iguaçu – PR – Brasil {caceres.mota,shindionishi}@hotmail.com, [email protected] Abstract. This article describes the use of annotations in the Java language, explaining the applications for the language pre-defined ann, creation of annot types, and its use within the frameworks Hibernate and FormBuilder. Resumo. Este artigo descreve o uso de anotações na linguagem Java, explicando as aplicações de anotações pré-definidas da linguagem, a criação de tipos, bem como o seu uso dentro dos frameworks Hibernate e Formbuilder. 1. Introdução Em 1991 a empresa Sun Microsystems, iniciou o projeto Green Project, no qual os criadores tinham a intenção de criar uma ligação entre os computadores e os aparelhos domésticos. A primeira criação da equipe foi o StartSeven, um controle remoto com interface touchscreen, cuja linguagem de programação foi nomeada Oak1 . Neste perı́odo, a internet começou a aumentar sua popularidade, sendo assim, a equipe do Green Project começou a adaptar a linguagem Oak para a internet, e em 1995 foi lançado o Java, uma versão atualizada do Oak para a internet [Mendes 2009]. Diferente das linguagens convencionais, que são compiladas para código nativo,a linguagem Java é compilada para um bytecode com extensão .class independente da arquitetura do sistema operacional utilizado. Esse .class poderá ser executado por qualquer JVM em qualquer ambiente operacional [Mendes 2009]. Este artigo tem a finalidade de apresentar um dos recursos da linguagem de programação Java chamado anotações, que foram introduzidas no Java na sua versão 5, cujo recurso é usado para anotar classes, campos e métodos, de tal forma que essas marcações possam ser tratadas pelo compilador, bibliotecas e ferramentas de desenvolvimento. 2. Objetivo Muitos programadores que utilizam a linguagem Java não tem o conhecimento de como funcionam, ou o que significam as anotações. O objetivo desse artigo é mostrar como é criado, o funcionamento, e as principais anotações pré definidas pela linguagem Java, além de apresentar alguns frameworks que utilizam anotações em seu funcionamento. 3. Anotações Básicas O sinal ”@”indica para o compilador que o que se segue é uma anotação. A anotação pode incluir elementos que podem ser nomeados e conterem valores. Sendo também possı́vel 1 Oak em português é Carvalho. utilizar varias anotações na mesma declaração. Se nas anotações múltiplas tiver mais de uma do mesmo tipo, denomina-se anotação de repetições2 [Zakhour et al. 2014]. A tabela 1 mostra alguns exemplos citados acima. Tabela 1. Exemplos Tipo Simples Anotação @Override @Autor( name = ”Fabricio Caceres Mota”, Com elementos date = ”2003/03/27”) ou @SuppressWarnings(value = ”unchecked”) Apenas valores @SuppressWarnings(”unchecked”) @Author(name = ”Fabricio”) Do mesmo tipo @Author(name = ”Regis”) 3.1. Anotações pré-definidas Existe um conjunto de anotações pré definidas na API do Java. Algumas dessas são utilizadas pelo compilador Java, e outras aplicáveis a outras anotações [Zakhour et al. 2014]. 3.1.1. Tipos de anotações utilizadas pelo compilador Java Os tipos de anotações pré-definido no java.lang são: • @Deprecated – Essa anotação indica que o elemento marcado é obsoleto e não deve ser mais usado. Quando um programa utiliza um método, classe, ou campo, com a anotação @Deprecated o compilador gera um aviso. Quando um elemento é substituı́do, ele também deve ser documentado usando a tag do Javadoc @deprecated como é mostrado no exemplo a seguir. O uso do sinal @ no comentário Javadoc e também na anotação indica que eles estão relacionados conceitualmente. Entretanto na tag do Javadoc começa com letra minúscula, já na anotação inicia-se com letra maiúscula. // Javadoc comment follows /** * @deprecated * explanation of why it was deprecated */ @Deprecated static void deprecatedMethod() { } Código 1. Exemplo de uso do @Deprecated. Adaptado de [Zakhour et al. 2014] • @Override – Essa anotação indica ao compilador de que o elemento é utilizado para substituir um elemento declarado da classe pai de uma herança, como mostrado no exemplo abaixo. 2 As repetições de anotações são suportadas a partir do Java SE 8 release // Metodo de marcacao como um metodo da classe Pai // que foi substituido @ Override int overriddenMethod () {} Código 2. Exemplo de uso do @Override. Adaptado de [Zakhour et al. 2014] Essa anotação não é obrigatória ao substituir um método, mas ajuda a evitar erros. Se o método marcado não substituir corretamente o método em uma de suas classes pai, o compilador gera um erro. • @SuppressWarnings – Essa anotação informa ao compilador para suprimir avisos especı́ficos que podem ser gerados. No exemplo a seguir um método @Deprecated que geralmente gera um aviso é usado. Neste caso a anotação faz com que o aviso não seja gerado. // Usar um metodo obsoleto e dizer ao // compilador nao gerar um aviso @ SuppressWarnings ("deprecation") void useDeprecatedMethod () { // Aviso de depreciacao Suprimida objectOne.deprecatedMethod (); } Código 3. Exemplo de uso do @SuppressWarnings. [Zakhour et al. 2014] Adaptado de Cada aviso de compilação pertence a uma categoria. A especificação da linguagem Java lista duas categorias: deprecation e unchecked. Para suprimir várias categorias de avisos, usamos a seguinte sintaxe: @ SuppressWarnings ({"unchecked", "deprecation"}) Código 4. Suprimindo várias categorias de avisos. [Zakhour et al. 2014] Adaptado de • @SafeVarargs – Essa anotação quando aplicada em um método ou construtor, afirma que o código não executa operações potencialmente perigosas em seu parâmetro. Quando esse tipo de anotação é usada, avisos não verificados relacionados ao parâmetro são suprimidos. • @FunctionalInterface – Adicionado no Java SE 8, a anotação indica que a declaração de tipo é destinada a ser uma interface funcional3 3.1.2. Anotações que se aplicam em outras anotações Segundo [Zakhour et al. 2014], os tipos de anotações que se aplicam em outras anotações são denominadas meta-anotações. Existem vários tipos de meta-anotações definidas no java.lang.annotation, como: • @Retention – Essa anotação especifica como a anotação marcada é armazenada: 3 Interfaces funcionais são interfaces com um único método abstrato. a) RetentionPolicy.SOURCE – A anotação marcada, é interpretada somente no código fonte e ignorada durante a compilação, b) RetentionPolicy.CLASS – A anotação marcada é retida somente durante a compilação do código, c) RetentionPolicy.RUNTIME – A anotação marcada é mantida pela JVM4 para que possa ser usada pelo ambiente de execução. • @Documented – Essa anotação indica sempre que a anotação especificada é usada, esses elementos devem ser documentados utilizando a ferramenta Javadoc. • @Target – Essa anotação restringe os tipos de elementos Java que podem ser aplicadas à outra anotação. a) ElementType.ANNOTATION TYPE – pode ser aplicada a um tipo de anotação, b) ElementType.CONSTRUCTOR – pode ser aplicada a um construtor, c) ElementType.FIELD – pode ser aplicada a um campo ou propriedade, d) ElementType.LOCAL VARIABLE – pode ser aplicado a uma variável local, e) ElementType.METHOD – pode ser aplicada a um método, f) ElementType.PACKAGE – pode ser aplicado a uma declaração de pacote, g) ElementType.PARAMETER – pode ser aplicado com os parâmetros de um método, h) ElementType.TYPE – pode ser aplicado a qualquer elemento de uma classe. • @Inherited – Indica que um tipo de anotação é automaticamente herdada. Se uma meta-anotação Inherited está presente em uma declaração de tipo de anotação, e o usuário consulta o tipo de anotação em uma declaração de classe, e a declaração de classe não tem nenhuma anotação para esse tipo, então a superclasse da classe será automaticamente consultada para o tipo de anotação. Este processo será repetido até que uma anotação para este tipo seja encontrado, ou o topo da hierarquia de classe (objeto) seja alcançado. Se nenhuma superclasse tenha uma anotação para este tipo, a consulta irá indicar que a classe em questão não tem essa anotação. Nota-se que este tipo de meta-anotação não tem efeito se o tipo de anotação é usada para anotar qualquer coisa diferente de uma classe e que esta meta-anotação só faz com que as anotações sejam herdadas de superclasses, assim, não tem efeito sobre interfaces. • @Repeatable – informa ao compilador que a anotação indicada pode ser usada várias vezes. (Disponı́vel a partir do Java 8) 3.2. Declarando uma anotação Muitas anotações substituem comentários no código. Suponha que um grupo de desenvolvedores de software tradicionalmente começam o corpo de toda classe com comentários provendo informações importantes: public class Generation3List extends Generation2List { // // // // 4 Author: John Doe Date: 3/17/2002 Current revision: 6 Last modified: 4/12/2004 Java Virtual Machine // By: Jane Doe // Reviewers: Alice, Bill, Cindy // class code goes here } Código 5. Exemplo de comentários. Adaptado de [Zakhour et al. 2014] Para adicionar o mesmo metadado com uma anotação, primeiramente deve-se definir o tipo de anotação. A sintaxe para fazer isso é: @interface ClassPreamble { String author(); String date(); int currentRevision() default 1; String lastModified() default "N/A"; String lastModifiedBy() default "N/A"; // Note use of array String[] reviewers(); } Código 6. Definindo o tipo de anotação. Adaptado de [Zakhour et al. 2014] A definição do tipo de anotação é similar a uma definição de interface onde a palavra-chave interface é precedido por um (@). O corpo da definição de anotação anterior contém declarações de elementos do tipo anotação, que se parecem muito com os métodos. Nota-se que eles podem definir os valores padrão opcionais. Após o tipo de anotação ser definida, pode-se usar anotações deste tipo, com valores preenchidos, como: @ClassPreamble ( author = "John Doe", date = "3/17/2002", currentRevision = 6, lastModified = "4/12/2004", lastModifiedBy = "Jane Doe", // Note array notation reviewers = {"Alice", "Bob", "Cindy"} ) public class Generation3List extends Generation2List { // class code goes here } Código 7. Utilizando a anotação definida. Adaptado de [Zakhour et al. 2014] Obs.: Para fazer com que as informações contidas em @ClassPreamble apareçam na documentação gerada pelo Javadoc, você deve anotar a definição @ClassPreamble com a anotação @Documented, @Documented annotation: // import this to use @Documented import java.lang.annotation.*; @Documented @interface ClassPreamble { // Annotation element definitions } Código 8. Documentando a anotação definida. Adaptado de [Zakhour et al. 2014] 4. Anotações em Frameworks Segundo [Fayad and Schmidt 1997], frameworks é um conjunto de classes que colaboram para realizar uma responsabilidade para um domı́nio de um subsistema da aplicação. Existem alguns frameworks que se utilizam de anotações para seu funcionamento. Nessa seção serão apresentados alguns dos frameworks para Java que utilizam anotações. 4.1. Formbuilder O framework FormBuilder, foi desenvolvido para automatizar a geração de telas PrimeFaces e agilizar o desenvolvimento para aplicações Web. O FormBuilder gera três tipos de componentes: botão, caixa de edição e caixa de marcação, esses componentes são gerados através de anotações declaradas nas classes de controle desenvolvidas. A ligação entre a classe de controle e a pagina web é realizada através de uma tag JSF5 customizada [Lohn and Vahldick 2013] . Segue abaixo um exemplo de utilização do framework, onde cada anotação Button foi associada a um método. (a) Declaração das anotações Button (b) Página gerada Figura 1. Exemplo de uso do Framework FormBuilder [Lohn and Vahldick 2013] 4.2. Hibernate ”O Hibernate é um framework object relacional mapping(ORM). É um framework que utiliza anotações ou arquivos xml para a persistência de objetos Java em um banco de dados relacional. O desenvolvedor define como os objetos são mapeados nas tabelas do banco e o Hibernate faz todo o acesso ao banco, gerando inclusive os comandos SQL se necessários”[Mrack 2006]. 5 Java Server Faces (JSF) é um framework MVC para a construção de interface de usuário em aplicações web. Na figura 2 tem-se um exemplo do framework Hibernate utilizando anotações. Segundo [Soares and da Costa Marchi 2013] as annotations auxiliam o Hibernate em como se deve criar os atributos na tabela do banco de dados, como por exemplo o @Entity que declara uma entidade do tipo relacional como uma tabela, porém ainda continua sendo uma classe Java, também tendo o @id que define o identificador da tabela e annotations utilizada para realizar associações, tais como @ManyToOne que define um atributo de muitos para um ou a annotation @OneToMany que define um atributo de um para muitos. Figura 2. Exemplo de classe [Soares and da Costa Marchi 2013]. com anotação de Hibernate 5. Conclusão O uso adequado das anotações pré-definidas do Java pode ser vantajoso para a melhor compreensão do funcionamento da classe, assim, considerado como boa prática o seu uso. Anotações personalizadas podem ser criadas para a resolução de problemas pontuais para os quais não se encontra ferramentas prontas, mas podem tornar difı́cil a futura manutenção de código se mal documentadas. Existe uma grande variedade de frameworks que se utilizam da praticidade das anotações, indicando que a aplicabilidade das anotações é extensa e promissora. Referências Fayad, M. and Schmidt, D. C. (1997). Object-oriented application frameworks. Commun. ACM, 40(10):32–38. Lohn, S. and Vahldick, A. (2013). Formbuilder: Framework para geração automática de telas primefaces com base em anotações. REAVI-Revista Eletrônica do Alto Vale do Itajaı́, 2(1):64–74. Mendes, D. R. (2009). Programação Java com Ênfase em Orientação a Objetos. Novatec, 1th edition. Mrack, M. (2006). Hibernate, uma visão geral sobre o framework padrão de fato para mapeamento objeto-relaciona. http://pt.slideshare.net/mmrack/workshop-hibernate-comcomentarios,acessado em 16 de maio de 2014. Soares, L. G. Z. and da Costa Marchi, K. R. (2013). Uma abordagem sobre mapeamento objeto relacional com hibernate. Zakhour, S. B., Kannan, S., and Gallardo, R. (2014). The java tutorials. http://docs. oracle.com/javase/tutorial/java/annotations/index.html. [Online; acessado em 16 de maio de 2014].