Java 注解(Annotation)使用方法归纳

Java注解Annotation使用方法归纳

简介

注解是从JDK5开始支持,是Java对元数据的一种特殊支持。与注释有一定区别,可以理解为代码上的特殊标记,通过这些标记我们可以在编译,类加载,运行等程序类的生命周期内被读取、执行相应的处理。通过注解开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息。注解是Java语言的一种强大的功能。

自定义注解

1.编写自定义注解

  • 注解的定义修饰符为@interface
  • 注解中可以添加成员变量,成员变量以方法的形式定义
  • 需要使用@Retention注解来规定它的生命周期(编译期间、运行时等)
  • 需要使用@Target注解来规定它的适用范围(类型、方法、字段、方法参数等)

例子一

import java.lang.annotation.*;

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,
        ElementType.CONSTRUCTOR,
        ElementType.FIELD,
        ElementType.PARAMETER,
        ElementType.TYPE,
        ElementType.ANNOTATION_TYPE})
public @interface TestAnnotation {

    String value();

}
说明
  • @Inherited注解规定了这个自定义注解是可以被继承的。(父类修饰子类继承)
  • 注解定义中 String value(); 通过方法的方式定义了注解的成员变量value
使用注解进行修饰
  • 使用TestAnnotation来给类、成员变量添加注解
  • value命名的成员变量可以直接以参数的形式赋值。
@TestAnnotation("Class Student")
public class Student {

    @TestAnnotation("constance field")
    public static final String CLASS_NAME = "Student";
    @TestAnnotation("field")
    private String name;


    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

例子二

  • 使用 default ${value} 的形式可以定义成员变量是否需要默认值。
import java.lang.annotation.*;

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,
        ElementType.CONSTRUCTOR,
        ElementType.FIELD,
        ElementType.PARAMETER,
        ElementType.TYPE,
        ElementType.ANNOTATION_TYPE})
public @interface TestAnnotationTwo {

    String message();
    String[] names() default {};

}
说明
  • 注解定义中 String message(); String[] names(); 通过方法的方式定义了注解的成员变量message和names,其中names为String数组
使用注解进行修饰
  • 非value命名的成员变量需要通过 fieldName = value 来进行赋值
  • 注解中可以为空(具有默认值)的成员变量可以不赋值
@TestAnnotationTwo(message = "Hello!")
public class StudentTwo {

    @TestAnnotationTwo(message = "Hi!", names = {"holo", "la"})
    private String id;

    @TestAnnotationTwo(message = "yes")
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

自定义注解处理

  • 一般定义好注解的生命周期、成员变量之后,还需要针对注解编写相应的处理程序,获取程序的元数据。

注解定义如下

import java.lang.annotation.*;

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,
        ElementType.CONSTRUCTOR,
        ElementType.FIELD,
        ElementType.PARAMETER,
        ElementType.TYPE,
        ElementType.ANNOTATION_TYPE})
public @interface TestAnnotation {

    String value();
}

使用自定义注解修饰代码

  • 例子中的Student通过@TestAnnotation注解分别修饰了类、字段、方法以及方法参数
@TestAnnotation("Class Student")
public class Student {
    @TestAnnotation("constance field")
    public static final String CLASS_NAME = "Student";

    @TestAnnotation("field")
    private String name;

    @TestAnnotation("Constructor")
    public Student(String name) {
        this.name = name;
    }

    @TestAnnotation("getter")
    public String getName() {
        return name;
    }

    @TestAnnotation("setter")
    public void setName(String name) {
        this.name = name;
    }

    @TestAnnotation("public method")
    public void printName() {
        System.out.println(name);
    }

    @TestAnnotation("public method with parameter")
    public void printName(@TestAnnotation("parameter") String name) {
        System.out.println(name);
    }
}

编写处理程序获取元数据

  • 获取类(type)上的注解及其变量value值
public void learnClassAnnotation() {
    Class<?> clazzStudent = Student.class;
    for (Annotation annotation : clazzStudent.getAnnotations()) {
        if (annotation instanceof TestAnnotation) {
            System.out.println(((TestAnnotation) annotation).value());
        }
        if (annotation.annotationType() == TestAnnotation.class) {
            System.out.println(((TestAnnotation) annotation).value());
        }
    }
}
  • 结果如下
Class Student
Class Student
  • 获取字段(field)上的注解及其变量value值
public void learnFieldAnnotation() {
    Class<?> clazz = Student.class;
    List<Field> fields = Arrays.asList(clazz.getDeclaredFields());
    fields.forEach(field -> {
        System.out.println("\n\n------------------------field " + field.getName());
        for (Annotation annotation : field.getAnnotations()) {
            if (annotation instanceof TestAnnotation) {
                System.out.println(((TestAnnotation) annotation).value());
            }
            if (annotation.annotationType() == TestAnnotation.class) {
                System.out.println(((TestAnnotation) annotation).value());
            }
        }
    });

}
  • 结果如下
------------------------field CLASS_NAME
constance field
constance field


------------------------field name
field
field
  • 获取构造器(constructor)上的注解及其变量value值
public void learnConstructorAnnotation() {
    Class<?> clazz = Student.class;
    List<Constructor<?>> constructors = Arrays.asList(clazz.getDeclaredConstructors());
    constructors.forEach(constructor -> {
        System.out.println("\n\n------------------------constructor " + constructor.getName());
        for (Annotation annotation : constructor.getAnnotations()) {
            if (annotation instanceof TestAnnotation) {
                System.out.println(((TestAnnotation) annotation).value());
            }
            if (annotation.annotationType() == TestAnnotation.class) {
                System.out.println(((TestAnnotation) annotation).value());
            }
        }
    });
}
  • 结果如下
------------------------constructor Student
Constructor
Constructor
  • 获取方法(method)上的注解及其变量value值
public void learnMethodAnnotation() {
    Class<?> clazz = Student.class;
    List<Method> methods = Arrays.asList(clazz.getMethods());
    methods.forEach(method -> {
        System.out.println("\n\n------------------------method " + method.getName());
        for (Annotation annotation : method.getAnnotations()) {
            if (annotation instanceof TestAnnotation) {
                System.out.println(((TestAnnotation) annotation).value());
            }
            if (annotation.annotationType() == TestAnnotation.class) {
                System.out.println(((TestAnnotation) annotation).value());
            }
        }
    });
}
  • 结果如下
------------------------method getName
getter
getter


------------------------method setName
setter
setter


------------------------method printName
public method
public method


------------------------method printName
public method with parameter
public method with parameter


------------------------method wait


------------------------method wait


------------------------method wait


------------------------method equals


------------------------method toString


------------------------method hashCode


------------------------method getClass


------------------------method notify


------------------------method notifyAll
  • 获取方法参数(parameter)上的注解及其变量value值
public void learnParameterAnnotation() {
    Class<?> clazz = Student.class;
    List<Method> methods = Arrays.asList(clazz.getMethods());
    for (Method method : methods) {
        System.out.println("\n\n-----------------------------------------------method " + method.getName());
        for (Parameter parameter : method.getParameters()) {
            System.out.println("------------------------parameter " + parameter.getName());
            for (Annotation annotation : parameter.getAnnotations()) {
                if (annotation instanceof TestAnnotation) {
                    System.out.println(((TestAnnotation) annotation).value());
                }
                if (annotation.annotationType() == TestAnnotation.class) {
                    System.out.println(((TestAnnotation) annotation).value());
                }
            }
        }
    }
}
  • 结果
-----------------------------------------------method getName


-----------------------------------------------method setName
------------------------parameter arg0


-----------------------------------------------method printName


-----------------------------------------------method printName
------------------------parameter arg0
parameter
parameter


-----------------------------------------------method wait


-----------------------------------------------method wait
------------------------parameter arg0
------------------------parameter arg1


-----------------------------------------------method wait
------------------------parameter arg0


-----------------------------------------------method equals
------------------------parameter arg0


-----------------------------------------------method toString


-----------------------------------------------method hashCode


-----------------------------------------------method getClass


-----------------------------------------------method notify


-----------------------------------------------method notifyAll

说明

  • 通过反射方式获取Annotation[]数组之后,可以通过下面两种方式来判断此注解是否就是你自定义的注解

1.通过 instanceof 操作,判断annotation对象是否是自定义注解类

annotation instanceof TestAnnotation

2.通过 Annotation 的 annotationType() 方法获取到annotation对象的类型,并同自定义注解类进行比对

annotation.annotationType() == TestAnnotation.class

注解处理工具类

  • 最后附上注解处理的工具类,定义了若干实用的注解处理方法,希望对朋友们有所帮助
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * Created by xuyh(Johnsonmoon) at 2018/1/3 11:43.
 */
public class AnnotationUtils {
    /**
     * get declared annotations of the given class
     *
     * @param clazz given class
     * @return annotations
     */
    public static Annotation[] getAnnotations(Class<?> clazz) {
        return clazz.getAnnotations();
    }

    /**
     * get declared annotations of the given field
     *
     * @param field given field
     * @return annotations
     */
    public static Annotation[] getAnnotations(Field field) {
        return field.getAnnotations();
    }

    /**
     * get declared annotations of the given method
     *
     * @param method given method
     * @return annotations
     */
    public static Annotation[] getAnnotations(Method method) {
        return method.getAnnotations();
    }

    /**
     * get declared annotations of the given constructor
     *
     * @param constructor given constructor
     * @return annotations
     */
    public static Annotation[] getAnnotations(Constructor constructor) {
        return constructor.getAnnotations();
    }

    /**
     * get declared annotations of the given parameter
     *
     * @param parameter given parameter
     * @return annotations
     */
    public static Annotation[] getAnnotations(Parameter parameter) {
        return parameter.getAnnotations();
    }

    /**
     * Is field has annotation of annotationType
     *
     * @param field          given field
     * @param annotationType given annotation type
     * @return true/false
     */
    public static boolean hasAnnotation(Field field, Class<?> annotationType) {
        Annotation[] annotations = field.getAnnotations();
        if (annotations == null || annotations.length == 0)
            return false;
        for (Annotation annotation : annotations) {
            if (annotation.annotationType() == annotationType)
                return true;
        }
        return false;
    }


    /**
     * Is clazz has annotation of annotationType
     *
     * @param clazz          given clazz
     * @param annotationType given annotation type
     * @return true/false
     */
    public static boolean hasAnnotation(Class<?> clazz, Class<?> annotationType) {
        Annotation[] annotations = clazz.getAnnotations();
        if (annotations == null || annotations.length == 0)
            return false;
        for (Annotation annotation : annotations) {
            if (annotation.annotationType() == annotationType)
                return true;
        }
        return false;
    }


    /**
     * Is method has annotation of annotationType
     *
     * @param method         given method
     * @param annotationType given annotation type
     * @return true/false
     */
    public static boolean hasAnnotation(Method method, Class<?> annotationType) {
        Annotation[] annotations = method.getAnnotations();
        if (annotations == null || annotations.length == 0)
            return false;
        for (Annotation annotation : annotations) {
            if (annotation.annotationType() == annotationType)
                return true;
        }
        return false;
    }


    /**
     * Is constructor has annotation of annotationType
     *
     * @param constructor    given constructor
     * @param annotationType given annotation type
     * @return true/false
     */
    public static boolean hasAnnotation(Constructor<?> constructor, Class<?> annotationType) {
        Annotation[] annotations = constructor.getAnnotations();
        if (annotations == null || annotations.length == 0)
            return false;
        for (Annotation annotation : annotations) {
            if (annotation.annotationType() == annotationType)
                return true;
        }
        return false;
    }


    /**
     * Is parameter has annotation of annotationType
     *
     * @param parameter      given parameter
     * @param annotationType given annotation type
     * @return true/false
     */
    public static boolean hasAnnotation(Parameter parameter, Class<?> annotationType) {
        Annotation[] annotations = parameter.getAnnotations();
        if (annotations == null || annotations.length == 0)
            return false;
        for (Annotation annotation : annotations) {
            if (annotation.annotationType() == annotationType)
                return true;
        }
        return false;
    }

    /**
     * Get annotation of given annotation type declared in given field.
     *
     * @param field          given field
     * @param annotationType given annotation type
     * @return annotation instance
     */
    public static Annotation getAnnotation(Field field, Class<?> annotationType) {
        Annotation[] annotations = field.getAnnotations();
        if (annotations == null || annotations.length == 0)
            return null;
        for (Annotation annotation : annotations) {
            if (annotation.annotationType() == annotationType)
                return annotation;
        }
        return null;
    }

    /**
     * Get annotation of given annotation type declared in given clazz.
     *
     * @param clazz          given clazz
     * @param annotationType given annotation type
     * @return annotation instance
     */
    public static Annotation getAnnotation(Class<?> clazz, Class<?> annotationType) {
        Annotation[] annotations = clazz.getAnnotations();
        if (annotations == null || annotations.length == 0)
            return null;
        for (Annotation annotation : annotations) {
            if (annotation.annotationType() == annotationType)
                return annotation;
        }
        return null;
    }

    /**
     * Get annotation of given annotation type declared in given method.
     *
     * @param method         given method
     * @param annotationType given annotation type
     * @return annotation instance
     */
    public static Annotation getAnnotation(Method method, Class<?> annotationType) {
        Annotation[] annotations = method.getAnnotations();
        if (annotations == null || annotations.length == 0)
            return null;
        for (Annotation annotation : annotations) {
            if (annotation.annotationType() == annotationType)
                return annotation;
        }
        return null;
    }

    /**
     * Get annotation of given annotation type declared in given constructor.
     *
     * @param constructor    given constructor
     * @param annotationType given annotation type
     * @return annotation instance
     */
    public static Annotation getAnnotation(Constructor<?> constructor, Class<?> annotationType) {
        Annotation[] annotations = constructor.getAnnotations();
        if (annotations == null || annotations.length == 0)
            return null;
        for (Annotation annotation : annotations) {
            if (annotation.annotationType() == annotationType)
                return annotation;
        }
        return null;
    }

    /**
     * Get annotation of given annotation type declared in given parameter.
     *
     * @param parameter      given parameter
     * @param annotationType given annotation type
     * @return annotation instance
     */
    public static Annotation getAnnotation(Parameter parameter, Class<?> annotationType) {
        Annotation[] annotations = parameter.getAnnotations();
        if (annotations == null || annotations.length == 0)
            return null;
        for (Annotation annotation : annotations) {
            if (annotation.annotationType() == annotationType)
                return annotation;
        }
        return null;
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用 Java 的反射机制来获取方法上的注解,并通过代理来修改注解的值。具体实现可以参考以下代码: ```java import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class AnnotationProxy { public static void main(String[] args) throws Exception { // 获取需要修改注解方法 Method method = MyClass.class.getMethod("myMethod"); // 获取方法上的注解 MyAnnotation annotation = method.getAnnotation(MyAnnotation.class); // 创建代理对象 MyAnnotation proxyAnnotation = (MyAnnotation) Proxy.newProxyInstance( MyAnnotation.class.getClassLoader(), new Class[]{MyAnnotation.class}, (proxy, method1, args1) -> { // 修改注解的值 if (method1.getName().equals("value")) { return "new value"; } else { return method1.invoke(annotation, args1); } }); // 修改方法上的注解 Annotation[] annotations = method.getDeclaredAnnotations(); for (int i = 0; i < annotations.length; i++) { if (annotations[i].annotationType() == MyAnnotation.class) { annotations[i] = proxyAnnotation; } } // 调用方法 MyClass myClass = new MyClass(); myClass.myMethod(); } @MyAnnotation("old value") static class MyClass { public void myMethod() { System.out.println("Hello, world!"); } } @interface MyAnnotation { String value(); } } ``` 在上面的代码中,我们使用Java 的反射机制来获取方法上的注解,并通过代理来修改注解的值。具体来说,我们创建了一个代理对象,然后在代理对象的方法中判断是否需要修改注解的值,如果需要就返回新的值,否则就调用原来的方法。最后,我们将修改后的注解赋值给方法上的注解数组,然后调用方法即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值