java中自定义注解

自定义注解

Java允许开发者在代码中定义自己的注解类型,用于标记和描述程序中的元素。自定义注解可以用于类、方法、字段等各种元素上,通过注解处理器可以在编译时或运行时对注解进行解析和处理。

代码示例1

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME) // 指定注解的保留策略为运行时
@Target(ElementType.METHOD) // 指定注解的作用目标为方法
@Documented
public @interface MyAnnotation {
    String value() default ""; // 定义一个成员变量,默认值为空字符串
    int count() default 0; // 定义一个成员变量,默认值为0
}

定义名为MyAnnotation的自定义注解。注解使用@interface关键字进行定义。注解的保留策略通过@Retention注解指定,RetentionPolicy.RUNTIME,表示注解在运行时仍然可用。注解的作用目标通过@Target注解指定ElementType.METHOD,表示注解可以用于方法上。

注解中可以定义成员变量,成员变量的定义方式与接口类似。定义了两个成员变量valuecount,并分别指定了默认值为空字符串和0。

使用自定义注解时,可以在目标元素上使用注解,并为成员变量赋值。例如:

public class MyClass {
    @MyAnnotation(value = "Hello", count = 5)
    public void myMethod() {
        // 方法体
    }
}

通过反射机制,可以在运行时获取注解的信息,并根据注解进行相应的处理。例如:

public class AnnotationProcessor {
    public static void processAnnotations(Class<?> clazz) {
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
                String value = annotation.value();
                int count = annotation.count();
                // 根据注解进行相应的处理
                System.out.println("Method: " + method.getName() + ", value: " + value + ", count: " + count);
            }
        }
    }
}

定义了AnnotationProcessor类,其中processAnnotations方法用于处理带有@MyAnnotation注解的方法。通过isAnnotationPresent方法判断方法是否带有指定的注解,然后通过getAnnotation方法获取注解的实例,进而获取注解的成员变量的值。


代码示例2

注解中的属性是数组类型,并且给出了默认值:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    String[] value() default {"default"};
}

定义了一个名为 MyAnnotation 的注解,有一个名为 value 的属性,类型为字符串数组。还给出了一个默认值为 {"default"}

可以在方法上使用这个注解,并为 value 属性提供自定义值,如下所示:

public class MyClass {
    @MyAnnotation(value = {"value1", "value2"})
    public void myMethod() {
        // do something
    }
}

在上面的代码中,在 myMethod 方法上使用了 MyAnnotation 注解,并为 value 属性提供了自定义值 {"value1", "value2"}


注解的保留策略和作用目标

保留策略参数:

Java中的注解有三种保留策略参数:

1. SOURCE:注解只保留在源代码中,编译时会被忽略。

2. CLASS:注解会被编译器保留在class文件中,但在运行时不会被JVM保留。

3. RUNTIME:注解会被编译器保留在class文件中,并在运行时被JVM保留,因此可以通过反射机制读取注解信息。

作用目标参数:

Java中的注解有多种作用目标参数,包括:

1. TYPE:用于类、接口、枚举等类型的声明。

2. FIELD:用于字段的声明。

3. METHOD:用于方法的声明。

4. PARAMETER:用于方法的参数声明。

5. CONSTRUCTOR:用于构造函数的声明。

6. LOCAL_VARIABLE:用于局部变量的声明。

7. ANNOTATION_TYPE:用于注解类型的声明。

8. PACKAGE:用于包的声明。

Documented注解的作用:

Documented注解是一个标记注解,用于指示被注解的元素应该包含在JavaDoc文档中。当一个注解被标记为Documented时,它将被包含在JavaDoc文档中,以便用户可以查看该注解的文档。

AliasFor注解

AliasFor注解是Spring框架中的一个注解,它用于指定注解属性之间的别名关系。在使用AliasFor注解时,需要指定别名关系的两个属性,其中一个属性作为主属性,另一个属性作为别名属性。当别名属性被设置时,主属性也会被自动设置,反之亦然。

AliasFor注解的使用场景主要有以下两种:

1. 用于注解属性之间的别名关系

在这种场景下,AliasFor注解用于指定注解属性之间的别名关系,以便在使用注解时可以使用别名属性来设置主属性。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation{
  
      @AliasFor("locations")
      String value() default "";
  
      @AliasFor("value")
      String locations() default "";
}

@MyAnnotation(value= "test")
public class MyClass {
    // ...
}

MyAnnotation注解,该注解含有value和locations两个属性,分别为value设置别名locations,locations设置别名value。在使用@MyAnnotation注解时无论是为value设置值,还是为locations设置值达到的效果相同。

使用限制:

 - 别名都是成对出现,为value属性设置locations别名,需要含有locations属性并为其设置value别名;
 - 成对出现的属性返回值相同;
 - 必须为成对出现的属性必须设置默认值;
 - 成对出现的属性的默认值必须相同;
 - AliasFor注解不能设置annotation属性;
 - 用于注解之间的别名关系

2. 用于注解之间的别名关系

在这种场景下,AliasFor注解用于指定不同注解之间的别名关系,以便在使用这些注解时可以使用别名注解来替代主注解。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation1 {
    String value() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@MyAnnotation1
public @interface MyAnnotation2 {
    @AliasFor(annotation = MyAnnotation1.class, attribute = "value")
    String name() default "";
}

@MyAnnotation2(name = "test")
public class MyClass {
    // ...
}

MyAnnotation2注解中的name属性和MyAnnotation1注解中的value属性之间存在别名关系。因此,在使用MyAnnotation2注解时,可以使用name属性来替代MyAnnotation1注解中的value属性,如上面的示例所示。

你可能感兴趣的:(java,开发语言)