当前位置:   article > 正文

深入浅出java注解_深入java注解

深入java注解

参考资料

参考链接1

如何定义一个注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface MyAnnotation {

    String title() default "";

    String[] urls() default "";

    boolean isTrue() default true;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

获取注解

反射

在这里插入图片描述

前提条件

只有 RetentionPolicy.RUNTIME 的注解可以被反射获取。

@Target(ElementType.TYPE)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Ann1 {
}

@Ann1
public class Ann1Client {
    public static void main(String[] args) {
        Annotation[] annotations = Ann1Client.class.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
ElementType.TYPE_PARAMETER
@Target(value = {
        ElementType.TYPE_PARAMETER
})
@Retention(RetentionPolicy.RUNTIME)
@interface Ann7 {
    String value();
}

@Target(value = {
        ElementType.TYPE_USE
})
@Retention(RetentionPolicy.RUNTIME)
public @interface Ann8 {
    String value();
}

public class UseAnn100<@Ann7("this is A") @Ann8("this is AA") A,
        @Ann7("this is B") @Ann8("this is BB") B,
        @Ann7("this is C") @Ann8("this is CC") C> {
    public static void main(String[] args) {
        TypeVariable<Class<UseAnn100>>[] typeParameters = UseAnn100.class.getTypeParameters();
        for (TypeVariable<Class<UseAnn100>> typeParameter : typeParameters) {
            Annotation[] annotations = typeParameter.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println(annotation);
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
ElementType.PACKAGE

在这里插入图片描述

@Target(value = {
        ElementType.PACKAGE
})
@Retention(RetentionPolicy.RUNTIME)
public @interface Ann9 {

    String value();
}

@Ann9("this is type package")
package com.example.lurenjia.spring.c16;

public class PackageInfoMain {
    public static void main(String[] args) {
        Package p = Package.getPackage("com.example.lurenjia.spring.c16");
        Annotation[] annotations = p.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
ElementType.METHOD
@Target(value = {
        ElementType.METHOD
})
@Retention(RetentionPolicy.RUNTIME)
public @interface Ann101 {
    String value();
}

public class UseAnn101 {

    @Ann101("a")
    public void a() {

    }

    public static void main(String[] args) {
        Method[] declaredMethods = UseAnn101.class.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            Annotation[] annotations = declaredMethod.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println(annotation);
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
ElementType.CONSTRUCTOR
@Target(value = {
        ElementType.CONSTRUCTOR
})
@Retention(RetentionPolicy.RUNTIME)
public @interface Ann102 {
    String value();
}

public class UseAnn102 {

    @Ann102(value = "const")
    public UseAnn102() {
    }

    public static void main(String[] args) {
        Constructor<?>[] declaredConstructors = UseAnn102.class.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            Annotation[] declaredAnnotations = declaredConstructor.getDeclaredAnnotations();
            for (Annotation declaredAnnotation : declaredAnnotations) {
                System.out.println(declaredAnnotation);
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
ElementType.PARAMETER
@Target(value = {
        ElementType.PARAMETER
})
@Retention(RetentionPolicy.RUNTIME)
public @interface Ann103 {
    String value();
}

public class UseAnn103 {
    public void a(@Ann103("a") int a, @Ann103("b") int b) {
    }
    public static void main(String[] args) {
        Method[] declaredMethods = UseAnn103.class.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            Parameter[] parameters = declaredMethod.getParameters();
            for (Parameter parameter : parameters) {
                Annotation[] annotations = parameter.getAnnotations();
                for (Annotation annotation : annotations) {
                    System.out.println(annotation);
                }
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
ElementType.FIELD
@Target(value = {
        ElementType.FIELD
})
@Retention(RetentionPolicy.RUNTIME)
public @interface Ann104 {
    String value();
}

public class UseAnn104 {

    @Ann104("a . ")
    int a;
    @Ann104("b . ")
    int b;

    public static void main(String[] args) {
        Field[] fields = UseAnn104.class.getDeclaredFields();
        for (Field field : fields) {
            Annotation[] annotations = field.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println(annotation);
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
ElementType.LOCAL_VARIABLE
@Target(value = {
        ElementType.LOCAL_VARIABLE
})
@Retention(RetentionPolicy.RUNTIME)
public @interface Ann105 {
    String value();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
public class UseAnn105 {
    public UseAnn105() {
    }

    public void a(int a, int b) {
    }     
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

由于在 jdk8的class文件也就是字节码中不保留局部变量上的注解信息,所以 ElementType.LOCAL_VARIABLE 暂时没有实际效果。

ElementType.ANNOTATION_TYPE
@Target(value = {
        ElementType.ANNOTATION_TYPE
})
@Retention(RetentionPolicy.RUNTIME)
public @interface Ann106 {
    String value();
}

@Target(value = {
        ElementType.FIELD
})
@Ann106("Ann106")
@Retention(RetentionPolicy.RUNTIME)
public @interface Ann104 {
    String value();
}

public class UseAnn106 {

    public static void main(String[] args) {
        Annotation[] annotations = Ann105.class.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
ElementType.TYPE_USE

可以当任何类型来使用

@Target({ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@interface Ann10 {
    String value();
}
  • 1
  • 2
  • 3
  • 4
  • 5

Aop

@Aspect
@Component
public class MyAnnotationAop {

    private final static Logger logger = LoggerFactory.getLogger(MyAnnotationAop.class);

    @Pointcut("@annotation(com.example.micannotation.annotation.MyAnnotation)")
    public void MyAnnotationPointcut() {

    }

    /**
     * 方式一
     * @param joinPoint
     */
    @Before("MyAnnotationPointcut()")
    public void before(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
        String title = annotation.title();
        logger.info(" 1 title = {}", title);
        Object[] args = joinPoint.getArgs();
        logger.info(Arrays.toString(args));
    }

    /**
     * 方式二
     * @param joinPoint
     * @param annotation
     */
    @Before("@annotation(annotation)")
    public void before(JoinPoint joinPoint, MyAnnotation annotation) {
        String title = annotation.title();
        logger.info(" 2 title = {}", title);
        Object[] args = joinPoint.getArgs();
        logger.info(Arrays.toString(args));
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

常见的注解

内置注解

@SuppressWarnings 消除警告

@Override 重写方法

@Deprecated 过时方法,不推荐使用

元注解

修饰注解的注解

指定注解的使用范围:@Target

 ElementType[] value();
 
public enum ElementType {
       /*类、接口、枚举、注解上面*/
    TYPE,
    /*字段上*/
    FIELD,
    /*方法上*/
    METHOD,
    /*方法的参数上*/
    PARAMETER,
    /*构造函数上*/
    CONSTRUCTOR,
    /*本地变量上*/
    LOCAL_VARIABLE,
    /*注解上*/
    ANNOTATION_TYPE,
    /*包上*/
    PACKAGE,
    /*类型参数上*/
    TYPE_PARAMETER,
    /*类型名称上*/
    TYPE_USE
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

注解的作用对象

指定注解的保留策略:@Retention

public @interface Retention {
    RetentionPolicy value();
}

public enum RetentionPolicy {
  	编译后丢弃,也就是java文件生效
    SOURCE,
    class文件生效,jvm运行时丢失   
    CLASS,
    jvm运行时仍然存在
    RUNTIME
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

@Documented

@Inherit:实现类之间的注解继承

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Ann21 {
}

@Ann21
public class UseAnn21 {
}

@Ann21
public interface UseAnn21_ {
}

public class UseAnn21Son extends UseAnn21 {
    public static void main(String[] args) {
        Annotation[] annotations = UseAnn21Son.class.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }
}

public class UseAnn21Son_ implements UseAnn21_{
    public static void main(String[] args) {
        Annotation[] annotations = UseAnn21Son_.class.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }
}

@com.example.lurenjia.spring.c16.Ann21()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

注意,接口的实现类不会继承接口上被 @Inherit 修饰的注解

@Repeatable重复使用注解

如果我们尝试重复使用一个注解,默认下会提示如下的错误。
在这里插入图片描述

不使用 @Repeatable 怎么实现 ?

@MyAnnotations(array = {@MyAnnotation(title = "is title"), @MyAnnotation(title = "is title2")})
---
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE, ElementType.METHOD})
@Documented
public @interface MyAnnotations {
    MyAnnotation[] array();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

使用 @Repeatable
需要定义两个注解,一个容器注解和一个原始注解。

@Target(value = {
        ElementType.TYPE_USE
})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Ann110s.class)
public @interface Ann110 {
    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
@Target(value = {
        ElementType.TYPE_USE
})
@Retention(RetentionPolicy.RUNTIME)
public @interface Ann110s {

    Ann110[] value();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

使用 @Repeatable 后多了一种使用方法

@Ann110("1")
@Ann110("2")
@Ann110("3")
@Ann110("4")
public class UseAnn110s {
    public static void main(String[] args) {

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/924879
推荐阅读
相关标签
  

闽ICP备14008679号