Articulo de referencia

Anotación de Java

En el lenguaje de programación Java , una anotación es una forma de metadatos sintácticos que se pueden agregar al código fuente Java , como un atributo . [ 1 ] Se pueden anotar...

En el lenguaje de programación Java , una anotación es una forma de metadatos sintácticos que se pueden agregar al código fuente Java , como un atributo . [ 1 ] Se pueden anotar clases , métodos , variables , parámetros y paquetes Java . Al igual que las etiquetas Javadoc , las anotaciones Java se pueden leer desde los archivos fuente. A diferencia de las etiquetas Javadoc , las anotaciones Java también se pueden incrustar y leer desde los archivos de clase Java generados por el compilador Java . Esto permite que la máquina virtual Java conserve las anotaciones en tiempo de ejecución y las lea mediante reflexión . [ 2 ] Es posible crear metaanotaciones a partir de las existentes en Java. [ 3 ]

Historia

La plataforma Java cuenta con varios mecanismos de anotación ad hoc , como el transientmodificador o la @Deprecatedetiqueta javadoc. La solicitud de especificación de Java JSR-175 introdujo la funcionalidad de anotación de propósito general (también conocida como metadatos ) en el proceso de la comunidad Java en 2002; fue aprobada en septiembre de 2004. [ 4 ]

Las anotaciones estuvieron disponibles en el propio lenguaje a partir de la versión 1.5 del Kit de Desarrollo de Java (JDK). La aptherramienta proporcionó una interfaz provisional para el procesamiento de anotaciones en tiempo de compilación en la versión 1.5 del JDK; JSR-269 formalizó esto y se integró en el compilador javac en la versión 1.6.

En C++26 , C++ añadió anotaciones para la reflexión que son similares a las anotaciones de Java.

Anotaciones integradas

Java define un conjunto de anotaciones que están integradas en el lenguaje. De las siete anotaciones estándar, tres forman parte de java.lang y las cuatro restantes se importan de java.lang.annotation. [ 5 ] [ 6 ]

En Jakarta EE (anteriormente Java Platform, Enterprise Edition), también existen las siguientes anotaciones jakarta.annotation(anteriormente javax.annotation): [ 7 ] [ 8 ]

Anteriormente existía una anotación, @ManagedBeanubicada en jakarta.annotation, que se utilizaba históricamente para declarar un Managed Bean, que son objetos gestionados por el contenedor que admiten un pequeño conjunto de servicios básicos como la inyección de recursos, las devoluciones de llamada del ciclo de vida y los interceptores. Sin embargo, se ha eliminado. [ 9 ] [ 10 ]

Ejemplo

Anotaciones integradas

Este ejemplo demuestra el uso de la @Overrideanotación. Indica al compilador que compruebe si las clases padre tienen métodos coincidentes. En este caso, se genera un error porque el gettype()método de la clase Cat no sobrescribe getType()el de la clase Animal como se desea, debido a la discrepancia en las mayúsculas y minúsculas . Si la anotación no estuviera presente, se crearía @Overrideun nuevo método con el nombre especificado en la clase Cat.gettype()

clase pública Animal { público void hablar () {}public String getType () { return "Animal genérico" ; } }public class Cat extends Animal { @Override public void speak () { // Esta es una buena anulación. System . out . println ( "Miau." ); }@Override public String gettype () { // Error de compilación debido a un error tipográfico: debería ser getType() en lugar de gettype(). return "Cat" ; } }

Anotaciones personalizadas

Las declaraciones de tipo de anotación son similares a las declaraciones de interfaz normales. Un signo de arroba (@) precede a la palabra clave "interface".

// @Twizzle es una anotación para el método toggle(). @Twizzle public void toggle () {}// Declara la anotación Twizzle. public @interface Twizzle {}

Las anotaciones pueden incluir un conjunto de pares clave-valor, que se modelan como métodos del tipo de anotación. Cada declaración de método define un elemento del tipo de anotación. Las declaraciones de métodos no deben tener parámetros ni una cláusula throws. Los tipos de retorno están restringidos a tipos primitivos , cadenas , clases, enumeraciones , anotaciones y matrices de los tipos anteriores. Los métodos pueden tener valores predeterminados .

// Igual que: @Edible(value = true) @Edible ( true ) Item item = new Carrot ();public @interface Edible { boolean value () default false ; }@Autor ( first = "Oompah" , last = "Loompah" ) Libro libro = nuevo Libro ( );public @interface Author { String first (); String last (); }

Las propias anotaciones pueden ir acompañadas de anotaciones que indiquen dónde y cuándo pueden utilizarse:

import java.lang.annotation.* ;@Retention ( RetentionPolicy . RUNTIME ) // Hace que esta anotación sea accesible en tiempo de ejecución mediante reflexión. @Target ({ ElementType . METHOD }) // Esta anotación solo se puede aplicar a métodos de clase. public @interface Tweezable {}

El compilador reserva un conjunto de anotaciones especiales (incluidas @Deprecated, @Overridey @SuppressWarnings) para fines sintácticos.

Las anotaciones son ampliamente utilizadas por los frameworks como una forma conveniente de aplicar comportamientos a clases y métodos definidos por el usuario que, de otro modo, tendrían que declararse en una fuente externa (como un archivo de configuración XML) o programáticamente (con llamadas a la API). [ 11 ] Por ejemplo, la biblioteca Project Lombok hace un uso extensivo de anotaciones para reducir el código repetitivo. [ 12 ] A continuación, por ejemplo, se muestra una clase de datos de Jakarta Persistence anotada :

paquete org.wikipedia.examples ;import java.io.Serializable ;import jakarta.persistence.Column ; import jakarta.persistence.Entity ; import jakarta.persistence.GenerationType ; import jakarta.persistence.GeneratedValue ; import jakarta.persistence.Id ; import jakarta.persistence.Table ;@Entity // Declara esto como un bean de entidad @Table ( name = "people" ) // Asigna el bean a la tabla SQL "people" public class Person implements Serializable { @Id // Asigna esto a la columna de clave primaria. @GeneratedValue ( strategy = GenerationType . AUTO ) // La base de datos generará nuevas claves primarias, no nosotros. private Integer id ;@Column ( longitud = 32 ) // Trunca los valores de la columna a 32 caracteres. private String nombre ;public Integer getId () { return id ; }public void setId ( Integer id ) { this . id = id ; }public String getName () { return nombre ; }public void setName ( String name ) { this . name = name ; } }

Las anotaciones no son llamadas a métodos y, por sí solas, no harán nada. En cambio, el objeto de la clase se pasa a la implementación de Jakarta Persistence en tiempo de ejecución , que luego extrae las anotaciones para generar un mapeo objeto-relacional .

A continuación se muestra un ejemplo completo:

paquete org.wikipedia.examples.annotation ;import java.lang.annotation.Documented ; import java.lang.annotation.ElementType ; import java.lang.annotation.Inherited ; import java.lang.annotation.Retention ; import java.lang.annotation.RetentionPolicy ; import java.lang.annotation.Target ;@Documented @Retention ( RetentionPolicy . RUNTIME ) @Target ({ ElementType . TYPE , ElementType . METHOD , ElementType . CONSTRUCTOR , ElementType . ANNOTATION_TYPE , ElementType . PACKAGE , ElementType . FIELD , ElementType . LOCAL_VARIABLE }) @Inherited public @interface Unfinished { public enum Priority { LOW , MEDIUM , HIGH } String value (); String [] changedBy () default "" ; String [] lastChangedBy () default "" ; Priority priority () default Priority . MEDIUM ; String createdBy () default "James Gosling" ; String lastChanged () default "2011-07-08" ; }
paquete org.wikipedia.examples.annotation ;public @interface UnderConstruction { String owner () default "Patrick Naughton" ; String value () default "El objeto está en construcción." ; String createdBy () default "Mike Sheridan" ; String lastChanged () default "2011-07-08" ; }

Luego, usando Jakarta Faces :

paquete org.wikipedia.examples.validators ;import jakarta.faces.application.FacesMessage ; import jakarta.faces.component.UIComponent ; import jakarta.faces.context.FacesContext ; import jakarta.faces.validator.Validator ; import jakarta.faces.validator.ValidatorException ;import org.wikipedia.examples.annotation.UnderConstruction ; import org.wikipedia.examples.annotation.Unfinished ; import org.wikipedia.examples.annotation.Unfinished.Priority ; import org.wikipedia.examples.util.Util ;@UnderConstruction ( owner = "Jon Doe" ) public class DateValidator implements Validator { public void validate ( FacesContext context , UIComponent component , Object value ) throws ValidatorException { String date = ( String ) value ; String errorLabel = "Por favor, introduzca una fecha válida." ; if ( ! component . getAttributes (). isEmpty ()) { errorLabel = ( String ) component . getAttributes (). get ( "errordisplayval" ); }if ( ! Util . validateAGivenDate ( date )) { @Unfinished ( changedBy = "Steve" , value = "whether to add message to context or not, confirm" , priority = Priority . HIGH ) FacesMessage message = new FacesMessage (); message . setSeverity ( FacesMessage . SEVERITY_ERROR ); message . setSummary ( errorLabel ); message . setDetail ( errorLabel ); throw new ValidatorException ( message ); } } }

Tratamiento

Cuando se compila el código fuente de Java, las anotaciones pueden ser procesadas por complementos del compilador llamados procesadores de anotaciones. Estos procesadores pueden generar mensajes informativos o crear archivos fuente o recursos Java adicionales, que a su vez pueden ser compilados y procesados. Sin embargo, los procesadores de anotaciones no pueden modificar el código anotado en sí. (Las modificaciones de código pueden implementarse utilizando métodos que van más allá de la Especificación del Lenguaje Java). El compilador de Java almacena condicionalmente los metadatos de las anotaciones en los archivos de clase, si la anotación tiene un valor RetentionPolicyde CLASSo RUNTIME. Posteriormente, la JVM u otros programas pueden buscar los metadatos para determinar cómo interactuar con los elementos del programa o cambiar su comportamiento.

Además de procesar una anotación usando un procesador de anotaciones, un programador Java puede escribir su propio código que use reflexión para procesar la anotación. Java SE 5 admite una nueva interfaz que se define en el java.lang.reflectpaquete. Este paquete contiene la interfaz llamada AnnotatedElementque es implementada por las clases de reflexión de Java, incluidas Class, Constructor, Field, Method, y Package. Las implementaciones de esta interfaz se usan para representar un elemento anotado del programa que se está ejecutando actualmente en la Máquina Virtual de Java. Esta interfaz permite que las anotaciones se lean de forma reflexiva.

La AnnotatedElementinterfaz proporciona acceso a las anotaciones con RUNTIMEretención. Este acceso se proporciona mediante los métodos getAnnotation, getAnnotations, y isAnnotationPresent. Dado que los tipos de anotación se compilan y almacenan en archivos de código de bytes al igual que las clases, las anotaciones devueltas por estos métodos se pueden consultar como cualquier objeto Java normal. A continuación se proporciona un ejemplo completo del procesamiento de una anotación:

paquete org.wikipedia.examples.annotation ;import java.lang.annotation.Retention ; import java.lang.annotation.RetentionPolicy ;// Esta es la anotación que se procesará // El valor predeterminado para Target es todos los elementos Java // Cambiar la política de retención a RUNTIME (el valor predeterminado es CLASS) @Retention ( RetentionPolicy . RUNTIME ) public @interface TypeHeader { // Valor predeterminado especificado para el atributo developer String developer () default "Unknown" ; String lastModified (); String [] teamMembers (); int meaningOfLife (); }
// Esta es la anotación que se aplica a una clase @TypeHeader ( developer = "Bob Bee" , lastModified = "2013-02-12" , teamMembers = { "Ann" , "Dan" , "Fran" }, meaningOfLife = 42 ) public class SetCustomAnnotation { // El contenido de la clase va aquí }
paquete org.wikipedia.examples ;// Este es el código de ejemplo que procesa la anotación import java.lang.annotation.Annotation ; import java.lang.reflect.AnnotatedElement ;public class UseCustomAnnotation { public static void main ( String [] args ) { Class < SetCustomAnnotation > classObject = SetCustomAnnotation . class ; readAnnotation ( classObject ); }static void readAnnotation ( AnnotatedElement element ) { try { System . out . println ( "Valores del elemento de anotación: %n" ); if ( element . isAnnotationPresent ( TypeHeader . class )) { // getAnnotation devuelve el tipo de anotación Annotation singleAnnotation = element . getAnnotation ( TypeHeader . class ); TypeHeader header = ( TypeHeader ) singleAnnotation ;System.out.printf ( " Desarrollador : %s%n" , header.developer ( ) ) ; System.out.printf ( " Última modificación : % s%n" , header.lastModified ( ) ) ;// teamMembers devuelto como String[] System.out.print ( " Miembros del equipo : " ); for ( String member : header.teamMembers ( ) ) { System.out.printf ( " % s , " , member ) ; } System.out.println ( ) ;System.out.println ( "Significado de la vida: %s%n " , header.meaningOfLife ( ) ) ; } } catch ( Exception e ) { e.printStackTrace ( ) ; } } }

Bibliotecas como JUnit utilizan el procesamiento de anotaciones para generar pruebas unitarias.

Véase también

Referencias

  1. "Anotaciones" . Sun Microsystems . Archivado del original el 25/09/2011 . Consultado el 30/09/2011 ..
  2. Sun Microsystems (2005). Especificación del lenguaje Java™ (3.ª ed.). Prentice Hall . ISBN  0-321-24678-0..
  3. Dare Obasanjo (2007). "UNA COMPARACIÓN DEL LENGUAJE DE PROGRAMACIÓN C# DE MICROSOFT CON EL LENGUAJE DE PROGRAMACIÓN JAVA DE SUN MICROSYSTEMS: Anotaciones de metadatos" . Dare Obasanjo. Archivado del original el 19 de septiembre de 2012. Consultado el 20 de septiembre de 2012 .
  4. Coward, Danny (2006-11-02). "JSR 175: Una función de metadatos para el lenguaje de programación Java™" . Java Community Process . Recuperado el 2008-03-05 .
  5. "Tipos de anotación predefinidos" . Oracle Corporation . Consultado el 17 de diciembre de 2016 .
  6. "Las anotaciones integradas : anotaciones estándar" . Consultado el 17 de diciembre de 2016 . 
  7. ^ "API de anotaciones de Yakarta 1.3.5 API" . Yakarta EE.UU. Consultado el 13 de agosto de 2025 .
  8. «Anotaciones de Yakarta» . Yakarta EE.UU. Consultado el 13 de agosto de 2025 .
  9. ^ "API de anotaciones de Yakarta 1.3.5 API" . Yakarta EE.UU. Consultado el 13 de agosto de 2025 .
  10. «Anotaciones de Yakarta» . Yakarta EE.UU. Consultado el 13 de agosto de 2025 .
  11. Yu, Zhongxing; Bai, Chenggang; Seinturier, Lionel; Monperrus, Martin (2021). "Caracterización del uso, evolución e impacto de las anotaciones Java en la práctica". IEEE Transactions on Software Engineering . 47 (5): 969– 986. arXiv : 1805.01965 . doi : 10.1109/TSE.2019.2910516 . ISSN 1939-3520 . 
  12. Proyecto Lombok (22 de abril de 2026). "Descripción general (Lombok)" . projectlombok.org . Proyecto Lombok.
  • Introducción a las anotaciones de Java 6 en el sitio web de Sun Developer Network.
  • Introducción a las anotaciones de Java por MM Islam Chisty Archivado el 28/03/2017 en Wayback Machine
  • Srinivasan, Krishna (11 de agosto de 2007). "Anotaciones en Java 5.0" . JavaBeat . Archivado del original el 31 de mayo de 2015.
  • Hunt, John (24 de febrero de 2006). "Sobre las anotaciones de Java" . The Register .
  • ¿Cómo crear e implementar anotaciones personalizadas en Java? So Many Word . 15 de febrero de 2014. Archivado del original el 23 de febrero de 2014.
  • Tutorial sobre anotaciones en Java con ejemplos . TutorialsDesk . 9 de octubre de 2014.
  • Thakor, Vicky (13 de octubre de 2015). "Comprendiendo las anotaciones en Java" . Java por ejemplos .