初步了解注解

注解

一、内置注解

注解 用法
@Overrite 方法重写时,在方法上添加满足重写的语法要求image-20220826145627204
@Deprecated 表示该方法已过时image-20220826145941061
@SuppressWarnings 编译器去忽略注解中声明的警告image-20220826150143126

二、元注解

修饰注解的注解。

1. @Target

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

表示这个注解能放到哪

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})

ElementType[]是一个枚举类的集合

1.8版本: 重点前五个

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    /** 翻译:类、接口(包括注释类型)或枚举声明 */ 
    TYPE,

    /** Field declaration (includes enum constants) */
    /** 翻译:字段声明(包括枚举常量)*/
    FIELD,

    /** Method declaration */
    /** 翻译:方法声明 */
    METHOD,

    /** Formal parameter declaration */
    /** 翻译:形式参数声明 */
    PARAMETER,

    /** Constructor declaration */
    /** 翻译:构造函数声明 */
    CONSTRUCTOR,

    /** Local variable declaration */
    /** 翻译:局部变量声明 */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    /** 翻译:注释类型声明 */
    ANNOTATION_TYPE,

    /** Package declaration */
    /** 翻译:包装声明 */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
     /** 翻译:类型参数声明 */

    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    /** 翻译:类型的使用 */
    TYPE_USE
}

2. @Retention

表示这个注解作用的时机。

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

RetentionPolicy 枚举类

/**
 * Annotation retention policy.  The constants of this enumerated type
 * describe the various policies for retaining annotations.  They are used
 * in conjunction with the {@link Retention} meta-annotation type to specify
 * how long annotations are to be retained.
 *
 * 翻译:注释保留策略。此枚举类型的常量描述保留注释的各种策略。它们被使用与{@link Retention}元注释类型一起指定注释将保留多长时间。
 * @author  Joshua Bloch
 * @since 1.5
 */
public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     * 翻译: 编译器将丢弃注释 人话:源文件
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     * 翻译: 注释将由编译器记录在类文件中,但不需要在运行时由VM保留。这是默认行为。 就是字节码
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     * 翻译: 注释将由编译器记录在类文件中,并在运行时由VM保留,因此可以反射地读取它们。 运行的时候这个最常用
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

3. @Documented

生成帮助文档后是否保留注解信息,保留就添加。

/**
 * Indicates that annotations with a type are to be documented by javadoc
 * and similar tools by default.  This type should be used to annotate the
 * declarations of types whose annotations affect the use of annotated
 * elements by their clients.  If a type declaration is annotated with
 * Documented, its annotations become part of the public API
 * of the annotated elements.
 *
 * 翻译:指示默认情况下,javadoc和类似工具将记录具有类型的注释。此类型应用于注释类型的声明,这些类型的注释会影响其客户端对注释元素的使用。如果一个类型声明用	
 * Documented进行了注释,那么它的注释将成为被注释元素的公共API的一部分。
 *
 * @author  Joshua Bloch
 * @since 1.5
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

三、自定义注解

自定义注解:

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

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;

@Target({TYPE, FIELD})
@Retention(value= RetentionPolicy.RUNTIME)
public @interface TestAnnoation {

    // 最大值
    int max() default 100;

    // 最小值
    int min() default 0;
}

实现业务:

import org.example.reflect.annotation.TestAnnoation;

import java.lang.reflect.Field;

public class MyScan {
    public static final void check(Object object) throws IllegalAccessException {
        // 反射
        Class clazz = object.getClass();
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            // 如果属性上打上了注解
            if (declaredField.isAnnotationPresent(TestAnnoation.class)) {
                declaredField.setAccessible(true);
                TestAnnoation annotation = declaredField.getAnnotation(TestAnnoation.class);
                int max = annotation.max();
                int min = annotation.min();
                int num = declaredField.getInt(object);
                if (max < num) {
                    throw new RuntimeException("数值" + num + "大于最大值" + max);
                } else if (min > num) {
                    throw new RuntimeException("数值" + num + "小于最小值" + min);
                }
            }
        }
    }
}

测试:

// -------------------------- 测试自定义注解 -------------------------------
        User userTest = new User(1);
        try {
            // 正常这里不用写 会有拦截器或者aop自己处理
            MyScan.check(userTest);
        } catch (Exception e) {
            e.printStackTrace();
        }

运行结果:

image-20220829092956093

posted @ 2022-08-29 09:33  雨溟  阅读(26)  评论(0)    收藏  举报