stringtranslate.com

anotación de Java

En el lenguaje de programación de computadoras Java , una anotación es una forma de metadatos sintácticos que se pueden agregar al código fuente de Java . [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 archivos fuente. A diferencia de las etiquetas Javadoc , las anotaciones Java también se pueden incrustar y leer desde archivos de clase Java generados por el compilador de Java . Esto permite que la máquina virtual Java retenga las anotaciones en tiempo de ejecución y las lea mediante reflexión . [2] Es posible crear metanotaciones a partir de las existentes en Java. [3]

Historia

La plataforma Java tiene varios mecanismos de anotación ad hoctransient , por ejemplo, el modificador o la @Deprecatedetiqueta javadoc. La Solicitud de especificación de Java JSR-175 introdujo la función de anotación de propósito general (también conocida como metadatos ) en el Proceso de la comunidad Java en 2002; obtuvo la aprobación en septiembre de 2004. [4] Las anotaciones estuvieron disponibles en el propio lenguaje a partir de la versión 1.5 del Java Development Kit (JDK). La aptherramienta proporcionó una interfaz provisional para el procesamiento de anotaciones en tiempo de compilación en JDK versión 1.5; JSR-269 formalizó esto y se integró en el compilador javac en la versión 1.6.

Anotaciones incorporadas

Java define un conjunto de anotaciones 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]

Anotaciones aplicadas al código Java:

Anotaciones aplicadas a otras anotaciones (también conocidas como "Meta anotaciones"):

Desde Java 7, se han agregado tres anotaciones adicionales al lenguaje.

Ejemplo

Anotaciones incorporadas

Este ejemplo demuestra el uso de la @Overrideanotación. Le indica al compilador que verifique las clases principales en busca de métodos coincidentes. En este caso, se genera un error porque el gettype()método de la clase Gato en realidad no anula getType()la clase Animal como se desea, debido a que no coinciden los casos . Si la anotación estuviera ausente, se crearía @Overrideun nuevo método de nombre en la clase Cat.gettype()

clase pública Animal { habla pública vacía () { }         public String getType () { return "animal genérico" ; } }      public class Cat extends Animal { @Override public void talk () { // Esta es una buena anulación. Sistema . afuera . println ( "Miau." ); }              @Override public String gettype () { // Error en tiempo de compilación debido a un error tipográfico: debería ser getType() no gettype(). devolver "gato" ; } }        

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 "interfaz".

 // @Twizzle es una anotación al método toggle(). @Twizzle alternancia de vacío público () { }       // Declara la anotación Twizzle. @interfaz pública 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 ningún parámetro ni una cláusula de lanzamiento. Los tipos de retorno están restringidos a primitivos , cadenas , clases, enumeraciones , anotaciones y matrices de los tipos anteriores. Los métodos pueden tener valores predeterminados .

 // Igual que: @Edible(valor = verdadero) @Edible ( verdadero ) Artículo elemento = nueva Zanahoria ();       public @interface comestible { valor booleano () predeterminado falso ; }         @Author ( primero = "Oompah" , último = "Loompah" ) Libro libro = nuevo Libro ();           public @interface Autor { Cadena primero (); Cadena última (); }        

Las propias anotaciones pueden incluir anotaciones para indicar dónde y cuándo se pueden utilizar:

 @Retention ( RetentionPolicy . RUNTIME ) // Hacer 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. @interface pública Tweezable { }        

El compilador reserva un conjunto de anotaciones especiales (incluidas @Deprecatedy ) con @Overridefines @SuppressWarningssintácticos.

Los marcos suelen utilizar anotaciones como una forma de aplicar convenientemente comportamientos a clases y métodos definidos por el usuario que, de otro modo, deben declararse en una fuente externa (como un archivo de configuración XML) o mediante programación (con llamadas API). La siguiente, por ejemplo, es una clase de datos JPA anotada :

@Entity // Declara esto como un bean de entidad @Table ( nombre = "personas" ) // Asigna el bean a la tabla SQL "personas" clase pública Persona implementa Serializable { @Id // Asigna esto a la columna de clave principal. @GeneratedValue ( estrategia = GenerationType . AUTO ) // La base de datos generará nuevas claves primarias, no nosotros. identificación entera privada ;                   @Column ( longitud = 32 ) // Truncar los valores de la columna a 32 caracteres. nombre de cadena privada ;       público entero getId () { identificación de retorno ; }       public void setId ( ID entero ) { this . identificación = identificación ; }         cadena pública getName () { nombre de retorno ; }       public void setName ( nombre de cadena ) { this . nombre = nombre ; } }        

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

A continuación se ofrece un ejemplo completo:

paquete com.annotation ; importar java.lang.annotation.Documented ; importar java.lang.annotation.ElementType ; importar java.lang.annotation.Inherited ; importar java.lang.annotation.Retention ; importar java.lang.annotation.RetentionPolicy ; importar 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 Sin terminar { enum público Prioridad { BAJO , MEDIO , ALTO } Valor de cadena (); Cadena [] cambiada por () predeterminada "" ; Cadena [] lastChangedBy () predeterminado "" ; Prioridad prioridad () Prioridad predeterminada . MEDIO ; Cadena creada por () predeterminada "James Gosling" ; Cadena lastChanged () predeterminada "2011-07-08" ; }                                 
paquete com.annotation ; public @interface UnderConstruction { Propietario de la cadena () predeterminado "Patrick Naughton" ; Valor de cadena () predeterminado "El objeto está en construcción". ; Cadena creada por () predeterminada "Mike Sheridan" ; Cadena lastChanged () predeterminada "2011-07-08" ; }                   
paquete com.validadores ; importar javax.faces.application.FacesMessage ; importar javax.faces.component.UIComponent ; importar javax.faces.context.FacesContext ; importar javax.faces.validator.Validator ; importar javax.faces.validator.ValidatorException ;     importar com.annotation.UnderConstruction ; importar com.annotation.Unfinished ; importar com.annotation.Unfinished.Priority ; importar com.util.Util ;    @UnderConstruction ( propietario = "Jon Doe" ) clase pública DateValidator implementa Validador { validación pública vacía ( contexto FacesContext , componente UIComponent , valor del objeto ) lanza ValidatorException { Fecha de cadena = ( Cadena ) valor ; String errorLabel = "Ingrese una fecha válida". ; if ( ! componente . getAttributes (). isEmpty ()) { errorLabel = ( String ) componente . obtenerAtributos (). obtener ( "errordisplayval" ); }                                  if ( ! Util . validarAGivenDate ( fecha )) { @Unfinished ( changedBy = "Steve" , valor = "si agregar mensaje al contexto o no, confirmar" , prioridad = Prioridad . ALTA ) Mensaje FacesMessage = new FacesMessage (); mensaje . setSeverity ( FacesMessage . SEVERITY_ERROR ); mensaje . establecerResumen ( etiquetaerror ); mensaje . setDetail ( etiquetaerror ); lanzar una nueva ValidatorException ( mensaje ); } } }                         

Procesando

Cuando se compila el código fuente de Java, las anotaciones se pueden procesar mediante complementos del compilador llamados procesadores de anotaciones. Los procesadores pueden producir mensajes informativos o crear archivos o recursos fuente Java adicionales, que a su vez pueden compilarse y procesarse. Sin embargo, los procesadores de anotaciones no pueden modificar el código anotado en sí. (Las modificaciones del código se pueden implementar utilizando métodos más allá de la especificación del lenguaje Java). El compilador de Java almacena condicionalmente metadatos de anotación en los archivos de clase, si la anotación tiene un RetentionPolicyof 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 utilizando un procesador de anotaciones, un programador de Java puede escribir su propio código que utilice la reflexión para procesar la anotación. Java SE 5 admite una nueva interfaz definida en el java.lang.reflectpaquete. Este paquete contiene la interfaz llamada AnnotatedElementque implementan las clases de reflexión de Java, incluidas Class, Constructor, Field, Methody Package. Las implementaciones de esta interfaz se utilizan para representar un elemento anotado del programa que se ejecuta actualmente en la máquina virtual Java. Esta interfaz permite leer las anotaciones de forma reflexiva.

La AnnotatedElementinterfaz proporciona acceso a anotaciones que tienen RUNTIMEretención. Este acceso lo proporcionan los métodos getAnnotation, getAnnotationsy isAnnotationPresent. Debido a que los tipos de anotaciones 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 de procesamiento de una anotación:

importar java.lang.annotation.Retention ; importar java.lang.annotation.RetentionPolicy ;  // Esta es la anotación que se procesará // El valor predeterminado para Target son 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 de desarrollador Desarrollador de cadenas () predeterminado "Desconocido" ; Cadena última modificación (); Cadena [] miembros del equipo (); int significadoDeVida (); }               
// Esta es la anotación que se aplica a una clase @TypeHeader ( desarrollador = "Bob Bee" , lastModified = "2013-02-12" , teamMembers = { "Ann" , "Dan" , "Fran" }, significadoDeVida = 42 )               clase pública SetCustomAnnotation { // El contenido de la clase va aquí }    
// Este es el código de ejemplo que procesa la anotación import java.lang.annotation.Annotation ; importar java.lang.reflect.AnnotatedElement ;  clase pública UseCustomAnnotation { public static void main ( String [ ] args ) { Clase <SetCustomAnnotation> classObject = SetCustomAnnotation .clase ; leerAnotación ( objeto de clase ); }                 static void readAnnotation ( elemento AnnotatedElement ) { intenta { System . afuera . println ( "Valores del elemento de anotación: \n" ); if ( element . isAnnotationPresent ( TypeHeader . class )) { // getAnnotation devuelve Tipo de anotación Anotación singleAnnotation = elemento . getAnnotation ( TypeHeader . clase ); encabezado TypeHeader = ( TypeHeader ) singleAnnotation ;                      Sistema . afuera . println ( "Desarrollador: " + encabezado . desarrollador ()); Sistema . afuera . println ( "Última modificación: " + encabezado . última modificación ());      // miembros del equipo devueltos como String [] System . afuera . imprimir ( "Miembros del equipo: " ); para ( miembro de cadena : encabezado . teamMembers ()) Sistema . afuera . imprimir ( miembro + ", " ); Sistema . afuera . imprimir ( "\n" );           Sistema . afuera . println ( "Significado de la vida: " + encabezado . significadoDeLaVida ()); } } catch ( Excepción excepción ) { excepción . imprimirStackTrace (); } } }          

Ver también

Referencias

  1. ^ "Anotaciones". Microsistemas solares . Archivado desde el original el 25 de septiembre de 2011 . Consultado el 30 de septiembre de 2011 ..
  2. ^ Microsistemas solares (2005). Especificación del lenguaje Java (TM) (3ª ed.). Prentice Hall . ISBN 0-321-24678-0..
  3. ^ Atrévete 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". Atrévete Obasanjo. Archivado desde el original el 19 de septiembre de 2012 . Consultado el 20 de septiembre de 2012 .
  4. ^ Cobarde, Danny (2 de noviembre de 2006). "JSR 175: una instalación de metadatos para el lenguaje de programación JavaTM". Proceso de la comunidad Java . Consultado el 5 de marzo de 2008 .
  5. ^ "Tipos de anotaciones predefinidos". Corporación Oráculo . Consultado el 17 de diciembre de 2016 .
  6. ^ "Las anotaciones integradas: anotaciones estándar" . Consultado el 17 de diciembre de 2016 .

enlaces externos