Las anotaciones (también conocidas como metadatos) proporcionamos una forma formal para que podamos agregar información en nuestro código, lo que nos permite usar estos datos muy convenientemente en algún momento posterior.
1. Sintaxis básica
Java SE5 tiene tres anotaciones estándar incorporadas
@Override: indica que la definición de método actual sobrescribirá los métodos en la superclase. Si deletree accidentalmente la ortografía incorrecta, o la firma del método no coincide con el método sobrescribido, el compilador emitirá un mensaje de error.
@Depreced: si el programador usa un elemento anotado, el compilador emitirá un mensaje de advertencia
@SupperSwarnings: Cierre el mensaje de advertencia del compilador inapropiado.
Java SE5 tiene cuatro meta anotaciones incorporadas
@Target: indica dónde se puede usar esta anotación. Posibles parámetros de elemento de elemento incluyen:
1) Constructor: la declaración del constructor
2) Campo: Declaración de dominio (incluidas las instancias de enum)
3) Local_variable: Declaración de variables locales
4) Método: Declaración del método
5) Paquete: Declaración de paquete
6) Parámetro: Declaración de parámetros
7) Tipo: clase, interfaz (incluido el tipo de anotación) o la declaración de enum
@Retention: indica en qué nivel guardar la información de anotación. Los parámetros de retención opcional incluyen:
1) Fuente: La anotación será descartada por el compilador
2) Clase: las anotaciones están disponibles en archivos de clase, pero la VM lo descartará
3) Tiempo de ejecución: VM también retendrá anotaciones durante el tiempo de ejecución, por lo que la información de anotación se puede leer a través del mecanismo de reflexión.
@Documented: incluya esta anotación en Javadoc
@Inherited: permita que las subclases hereden anotaciones en las clases parentales la mayor parte del tiempo, los programadores definen principalmente sus propias anotaciones y escriben sus propios procesadores para manejarlos.
Usecase.java
paquete com; import java.lang.annotation.ElementType; import java.lang.annotation.retention; import java.lang.annotation.retentionPolicy; import java.lang.annotation.target; @Target (elementType.method) // Usar para definir dónde se aplicará su anotación, y esto se aplica como un método // Use para definir en qué nivel está disponible la anotación, en el código fuente (clase) o Runtime (Runtime) @Retention (retentionPolicy.runtime) public @interface useCase {Public int id (); Public String Descripción () predeterminado "Sin descripción"; } Contraseña. Java paquete com; Public Class PasswordUtils {@usecase (id = 47, descripción = "Las contraseñas deben contener al menos un numérico") public boolean validatePassword () {return true; } @Usecase (id = 48) public String CiCryptPassword (String Password) {return Password; } @Usecase (id = 49, descripción = "jong_cai") public void showeamame () {system.out.println ("jong_cai"); }}
2. Escribir procesador de anotaciones
Si no hay una herramienta para leer anotaciones, las anotaciones no serán más útiles que las anotaciones. En el proceso de uso de anotaciones, una parte importante es crear y usar procesadores de anotación. Java SE5 extiende la API del mecanismo de reflexión para ayudar a los programadores a construir tales herramientas. Al mismo tiempo, también proporciona una herramienta externa apta para ayudar a los programadores a analizar el código fuente de Java con anotaciones. A continuación se muestra un procesador de anotación muy simple, que usaremos para leer la clase PasswordUtils y usar el mecanismo de reflexión para encontrar la etiqueta @USECASE. Le proporcionamos un conjunto de valores de identificación, y luego enumera los casos de uso que se encuentran en contraseñas, así como los casos de uso faltantes.
USECASETRACKER.JAVA PACPACK COM; import java.lang.reflect.method; import java.util.arrayList; import java.util.collections; import java.util.list; clase pública USECASETRACKER {public static void backUsecases (List <Integer> List, class <?> cl) {for (método m: cl.getDeClaredMethods ()) {useCase us = m.getAnnotation (useCase.class); if (us! = null) {system.out.println ("caso de uso encontrado:" + us.id () + "" + us.description ()); list.remove (nuevo entero (us.id ())); }} para (int i: list) {System.out.println ("ADVERTENCIA: Caso de uso faltante-" + I); }} public static void main (string [] args) {list <integer> list = new ArrayList <Integer> (); Colección.addall (lista, 47,48,49,50,51); TrackUsecases (List, PasswordUtils.class); }}
Este programa utiliza dos métodos de reflexión: getDeclaredMethods () y getAnnotation (). Ambos pertenecen a la interfaz AnnotatedElement (clase, método y campo y otras clases implementan esta interfaz). El método getAnnotation () devuelve un objeto de anotación del tipo especificado, que es USECase. Si el método anotado no tiene una anotación del tipo, devuelve un valor nulo. Luego extraemos el valor del elemento del objeto USECase devuelto llamando a los métodos id () y description (). El método CiCryptPassword () no especifica el valor de descripción al anotar, por lo que cuando el procesador procesa su anotación correspondiente, el método Descripción () se obtiene el valor predeterminado, el método Descripción ().
La anotación se está extendiendo en el mundo de Java. Si tiene tiempo, escriba este artículo de anotaciones simples. Es una introducción a la anotación. Espero que puedas tirar un ladrillo y aprender juntos ...
Si deja de hablar sin sentido, la práctica es el resultado final.
3. Ejemplo
Hablemos primero sobre el concepto de anotación y luego hablemos sobre cómo diseñar su propia anotación.
Primero, en el paquete java.lang.annotation que viene con JDK, abra los siguientes archivos de origen:
Archivo de origen Target.java
@Documented @Retention (retenciónPolicy.Runtime) @Target (elementType.annotation_type) public @Interface Target {elementType [] value (); @Documented @Retention (retenciónPolicy.Runtime) @Target (elementType.annotation_type) public @Interface Target {elementType [] value (); }
@Interface es una palabra clave. Al diseñar anotaciones, un tipo debe definirse como @Interface, y no puede usar palabras clave de clase o interfaz (¿cree que Sun es un poco sólido, pero se ve muy similar a la interfaz)?
Retención de archivos de origen.java
@Documented @Retention (retentionPolicy.Runtime) @Target (elementType.annotation_type) public @Interface Retentent {Retentepolicy Value (); } @Documented @Retention (retentionPolicy.Runtime) @Target (elementType.annotation_type) public @Interface Retentent {retentionPolicy Value (); }
Después de ver esto, puede ser vago y no sabes de qué estás hablando. No te preocupes, eche un vistazo. Los archivos anteriores usan las dos campos de retención y elementType, y puede suponer que estos son dos archivos Java. De hecho, los códigos fuente de estos dos archivos son los siguientes:
Fuente de archivo RetentionPolicy.java
Public Enum RetententPolicy {fuente, clase, tiempo de ejecución} public enum retenciónpolicy {fuente, clase, tiempo de ejecución} Este es un tipo enum, con tres valores, a saber, fuente, clase y tiempo de ejecución.
La fuente significa que la información del tipo de anotación solo se conservará en el código fuente del programa. Si se compila el código fuente, los datos de anotación desaparecerán y no se conservarán en el archivo .class compilado.
La clase significa que la información del tipo de anotación se conserva en el código fuente del programa, y también se conservará en el archivo .class compilado. Al ejecutar, esta información no se cargará en la máquina virtual (JVM). Tenga en cuenta que cuando no establece un valor de retención del tipo de anotación, el valor predeterminado del sistema es clase.
El tercero es el tiempo de ejecución, lo que significa que la información se conserva en el código fuente y el archivo .class compilado, y esta información se cargará en el JVM durante la ejecución.
Por ejemplo, si la retención en @Override se establece en la fuente, si la compilación es exitosa, no necesita esta información verificada; Por el contrario, la retención en @Depreced se establece en tiempo de ejecución, lo que significa que, además de advertirnos, qué método se usa durante la compilación, también puede verificar si el método está desaprobado al ejecutar.
Archivo de origen Elemtype.java
public enum elementType {tipo, campo, método, parámetro, constructor, local_variable, annotation_type, paquete} public enum elementtype {type, campo, método, parámetro, constructor, local_variable, annotation_type, paquete}} @El elemento de elemento en el objetivo se usa para especificar qué tipo de anotación de elementos se puede usar. Expliquemos: Tipo (Tipo), Field (Atributo), Método (Método), Parámetro (Parámetro), Constructor (Constructor), Local_Variable (Variable local), Annotation_Type, Paquete (paquete), donde tipo (tipo) se refiere a que se usa en la clase, la interfaz, los tipos de enumes y la anotación.
Además, se puede ver en el código fuente de 1 que el propio @Target también se usó para declararse a sí mismo, y solo se pudo usar en Annotation_Type.
Si un tipo de anotación no especifica qué elementos se usa @Target, se puede usar en cualquier elemento, y el elemento aquí se refiere a los ocho tipos anteriores.
Déjame darte algunos ejemplos correctos:
@Target (elementType.method)
@Target (valor = elementtype.method)
@Target (elementtype.method, elementtype.constructor)
Consulte la documentación de Javadoc para más detalles
Todos los archivos de origen usan @Documented. El propósito de @Documented es habilitar esta información de tipo de anotación que se muestre en el documento de descripción de Javaapi; Si no se agrega, la información generada por este tipo no se encontrará cuando se use Javadoc para generar el documento API.
Otro punto es que si necesita heredar los datos de anotación en una subclase, usará el tipo de anotación @inherited.
El siguiente es el ejemplo de anotación más simple para diseñar, que consta de cuatro archivos;
Descripción.Java
paquete ligero.javaeye.com; import java.lang.annotation.documented; import java.lang.annotation.ElementType; import java.lang.annotation.retention; import java.lang.annotation.retentionPolicy; import java.lang.annotation.target; @Target (ElementType.Type) @Retention (retentionPolicy.Runtime) @Documented public @Interface Descripción {String Value (); } paquete ligero.javaeye.com; import java.lang.annotation.documented; import java.lang.annotation.ElementType; import java.lang.annotation.retention; import java.lang.annotation.retentionPolicy; import java.lang.annotation.target; @Target (ElementType.Type) @Retention (retentionPolicy.Runtime) @Documented public @Interface Descripción {String Value (); }
Nota: Todas las anotaciones heredarán automáticamente la interfaz java.lang.annotation, por lo que no puede heredar otras clases o interfaces.
El punto más importante es cómo establecer los parámetros en el tipo de anotación:
Primero, solo puede usar derechos de acceso público o predeterminado para modificarlo. Por ejemplo, valor de cadena (); Aquí establece el método al tipo predeterminado predeterminado.
En segundo lugar, los miembros de los parámetros solo pueden usar ocho tipos de datos básicos: byte, short, char, int, long, float, doble, booleano y tipos de datos como cadena, enum, clase, anotaciones, así como matrices de estos tipos. Por ejemplo, valor de cadena (); El miembro del parámetro aquí es cadena.
Tercero, si solo hay un miembro de parámetro, es mejor establecer el nombre del parámetro en "valor" y agregar soportes después. Ejemplo: el ejemplo anterior tiene solo un miembro de parámetro.
Nombre.java
paquete ligero.javaeye.com; import java.lang.annotation.documented; import java.lang.annotation.ElementType; import java.lang.annotation.retention; import java.lang.annotation.retentionPolicy; import java.lang.annotation.target; // Tenga en cuenta que el @Target aquí es diferente de @Description, y los miembros de los parámetros también son diferentes @Target (elementType.method) @Retention (retentionPolicy.Runtime) @documented public @Interface Name {String Originate (); String Community (); } paquete ligero.javaeye.com; import java.lang.annotation.documented; import java.lang.annotation.ElementType; import java.lang.annotation.retention; import java.lang.annotation.retentionPolicy; import java.lang.annotation.target; // Tenga en cuenta que el @Target aquí es diferente de @Description, y los miembros de los parámetros también son diferentes @Target (elementType.method) @Retention (retentionPolicy.Runtime) @documented public @Interface Name {String Originate (); String Community (); }
Javaeyer.java
paquete ligero.javaeye.com; @Description ("javaeye, ser la mejor comunidad de intercambio de desarrollo de software") clase pública Javaeyer {@name (originado = "Founder: Robbin", Community = "Javaeye") public String getName () {return null; } @Name (originado = "Fundador: Jiangnan Baiyi", Community = "Springside") public String getName2 () {return "Tome prestado dos identificaciones de identificaciones, ¡perdóname por escribir este ejemplo!"; }} paquete ligero.javaeye.com; @Description ("javaeye, ser la mejor comunidad de intercambio de desarrollo de software") clase pública Javaeyer {@name (originado = "Founder: Robbin", Community = "Javaeye") public String getName () {return null; } @Name (originado = "Fundador: Jiangnan Baiyi", Community = "Springside") public String getName2 () {return "Tome prestado dos identificaciones de identificaciones, ¡perdóname por escribir este ejemplo!"; }}Escriba una clase de testanotación que pueda ejecutar la información de extracto de Javaeyer
paquete ligero.javaeye.com; import java.lang.reflect.method; import java.util.hashset; import java.util.set; Public Class TestAnnotation { / *** Autor encendedor* Nota: Para más detalles, consulte la documentación de Javadoc para el uso de la anotación API* / public static void main (string [] args) lanza la excepción {String class_name = "Lighter.javaeye.com.Javaeyer"; Class test = class.forname (class_name); Método [] método = test.getMethods (); bandera booleana = test.isannotationPresent (descripción.class); if (flag) {descripción des = (descripción) test.getAnnotation (descripción.class); System.out.println ("Descripción:"+des.value ()); System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Hashset <Set Method> (); System.out.println ("Community creado:"+name.community ()); Anotación api*/ public static void main (string [] args) lanza la excepción {String class_name = "Lighter.javaeye.com.javaeyer"; Class test = class.forname (class_name); Método [] método = test.getMethods (); bandera booleana = test.isannotationPresent (descripción.class); if (flag) {descripción des = (descripción) test.getAnnotation (descripción.class); System.out.println ("Descripción:"+des.value ()); System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- { Boolean OtherFlag = Method [i] .IsannotationPresent (name.class); Resultados de ejecución:
Descripción: Javaeye, The Best Software Development Exchange Community Fundador: Robbin Comunidad creada: Javaeye Fundador: Javaeye Comunidad creada: Springside