[Conceptos básicos de Java] Anotaciones - Anotaciones personalizadas

¿Qué son las anotaciones?

La anotación de Java (Annotation), también conocida como anotación de Java, es un mecanismo de anotación introducido por JDK5.0. Por ejemplo, nuestros comunes @Override y @Deprecated son anotaciones. Las anotaciones se pueden agregar a clases, métodos, variables miembro, etc., de forma similar a " etiquetarlas ".

¿Cómo se definen las anotaciones?

El nombre de la anotación de la @interfaz pública {} se parece mucho a la interfaz de definición, excepto que hay una interfaz de símbolo @ adicional: anotación del nombre de la interfaz de la interfaz pública : nombre de la anotación de la @interfaz pública

public @interface lkx {
    
    
    
}

¿Cómo usar las anotaciones?

Ahora que se han definido nuestras anotaciones, podemos usar directamente "nombre de anotación @" al usarlas. Por ejemplo, podemos definirlas en " clases, variables miembro y métodos miembro " de la siguiente manera:

@lkx
public class Test {
    
    
    @lkx
    private int num;
    
    @lkx
    public static void main(String[] args) {
    
    
        System.out.println("hello");
    }
}
  • pensar por un tiempo

Ahora que la anotación se ha definido y utilizado, pero no quiero definirla en la clase o el método miembro, solo quiero definirla en el método miembro. ¿Cómo puedo hacer que la anotación solo se defina en el método y el informe? un error cuando se define en otro lugar? El efecto deseado: inserte la descripción de la imagen aquí

En este momento, es necesario usar metanotaciones para limitar el alcance.

anotación meta

En términos simples, las meta-anotaciones son anotaciones definidas en annotations.Hay cuatro meta-anotaciones en Java @Target @Retention @Documented @Inherited

@Objetivo

@Target se usa para describir el alcance de la definición de la anotación, que puede limitar el tipo de elemento definido por esta anotación.

parámetro efecto
TipoDeElemento.ANOTATION_TYPE Se puede aplicar a tipos de anotaciones.
ElementType.CONSTRUCTOR se puede aplicar al constructor
ElementType.FIELD Se puede aplicar a campos o propiedades.
TipoDeElemento.LOCAL_VARIABLE se puede aplicar a variables locales
ElementType.METHOD Se puede aplicar a las anotaciones a nivel de método
TipoDeElemento.PAQUETE Se puede aplicar a declaraciones de paquetes.
ElementType.PARAMETER parámetros que se pueden aplicar a los métodos
TipoDeElemento.TIPO Se puede aplicar a cualquier elemento de la clase.

Debido a que queremos restringir solo a las variables miembro, debemos usar ElementType.FIELD

@Target(ElementType.FIELD)
public @interface lkx {
    
    

}

Pero, ¿qué pasa si queremos definir tanto las variables de miembro como los métodos de miembro al mismo tiempo? Los parámetros múltiples solo necesitan estar encerrados entre llaves y separados por comas.

@Target({
    
    ElementType.FIELD,ElementType.METHOD})
public @interface lkx {
    
    

}

Ahora solo las anotaciones definidas en la clase reportan un errorinserte la descripción de la imagen aquí

@Retención

@Retention se utiliza para definir el ciclo de vida de las anotaciones y también puede entenderse como un método de almacenamiento.

parámetro efecto
RetentionPolicy.SOURCE Las anotaciones marcadas se mantienen solo en el nivel de origen y el compilador las ignora.
RetentionPolicy.CLASS El compilador conserva las anotaciones marcadas en el momento de la compilación, pero la máquina virtual de Java (JVM) las ignora.
RetentionPolicy.RUNTIME La JVM conserva las anotaciones marcadas, por lo que el entorno de tiempo de ejecución puede usarlas.

Las siguientes dos meta-anotaciones no se usan mucho, por lo que no las explicaré en detalle por el momento.

@Documentado

@Documentado se utiliza para describir si se debe conservar su información de anotación al generar documentos de ayuda.

@Heredado

@Inherited se usa para describir si la anotación modificada por él se hereda.

elemento de anotación

Acabamos de definir una anotación arriba, pero no podemos pasar ninguna información, es simplemente equivalente a una etiqueta. Ahora veamos cómo definir parámetros para la anotación:

@Target({
    
    ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface lkx {
    
    
    String name() default "张三"; //可以使用default定义默认的值
    int age();
}

Ahora veamos cómo pasar parámetros:

public class Test {
    
    

    //name有默认值,也可以不写
    @lkx(name = "李四",age = 18)
    private int num;
    
    public static void main(String[] args) {
    
    
        System.out.println("hello");
    }
}

combate

Ahora que se han definido las anotaciones y se han pasado los parámetros, ¿todavía se pregunta para qué sirven las anotaciones? . . Ahora tenemos un pequeño requisito para asignar los parámetros pasados ​​en la anotación a las variables miembro. Por ejemplo:

@lkx(name = "李四",age = 18)
private int num; //num没有被赋值,等于0

赋值完成后
num = 18

Precauciones:

  1. El siguiente código necesita usar reflexión, si no sabes cómo hacerlo, puedes leer mis artículos anteriores.
  2. Debido a que necesita usar la reflexión para obtener parámetros de anotación, @Retention debe definirse como RetentionPolicy.RUNTIME

Código de implementación:

@Target({
    
    ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface lkx {
    
    
    String name() default "张三";
    int age();
}
java复制代码public class Test {
    
    

    //name有默认值,也可以不写
    @lkx(name = "李四",age = 18)
    private static int num;

    @lkx(name = "王五",age = 38)
    private static int age;

    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
    
    
        System.out.println("赋值前: num: " + num+"   age: "+age);

        //拿到类的字节码
        Class<Test> testClass = Test.class;
        //拿到所有成员变量
        for (Field declaredField : testClass.getDeclaredFields()) {
    
    
            //检测成员变量上是否有@lkx注解
            if (declaredField.isAnnotationPresent(lkx.class)) {
    
    
                lkx annotation = declaredField.getAnnotation(lkx.class);
                //获取到注解中的age的值
                int age = annotation.age();
                declaredField.set(testClass.newInstance(),age);
            }
        }

        System.out.println("赋值后: num: " + num+"   age: "+age);
    }
}

resultado de la operación:

java复制代码赋值前: num: 0   age: 0
赋值后: num: 18   age: 38

Supongo que te gusta

Origin blog.csdn.net/weixin_50799082/article/details/131236558
Recomendado
Clasificación