美文网首页
Java基础之注解Annotation

Java基础之注解Annotation

作者: hysea | 来源:发表于2020-08-21 16:37 被阅读0次
Java之注解.png

Java 注解用于为 Java 代码提供元数据。作为元数据,注解并不会直接影响你的代码执行。

1. 注解的定义

注解的定义与类的定义有些类似,只是将class换成@interfacexiu即可

public @interface AnnoTest {
    
}

但仅仅被@interface修饰还不够,一个完整的自定义注解还需要配合元注解使用。所以还先需要了解元注解是什么?怎么使用?

2. 注解分类

  • JDK自带注解:@Override、@Deprecated、@SuppressWarning
  • 元注解:@Target、@Retention、@Inherited、@Documented
  • 自定义注解
2.1 JDK自带注解
  • @Override:表示为被重写的方法
  • @Deprecated:表示过时的方法
  • @SuppressWarning:表示忽略警告
2.2 元注解

用来标记注解的注解

  • @Target

表示注解的作用域,通过枚举类ElementType表达作用类型,可以是类,方法,方法参数变量等。

其中枚举类ElementType的取值如下:

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, // 作用于注解(@Retention注解中就使用该属性)

    /** Package declaration */
    PACKAGE, // 作用于包

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER, // 作用于类型泛型,即泛型方法、泛型类、泛型接口 (jdk1.8加入)

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}
  • @Retention

表示注解存在的生命周期。注解存在阶段是保留在源码(编译期),字节码(类加载)或者运行期(JVM中运行)。通过枚举类RetentionPolicy来表示注解保留时期。

其中枚举类RetentionPolicy的取值如下:

public enum RetentionPolicy {
    /**
     * 注解只存在源码中,编译时会丢弃
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
     * 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.
     */
    CLASS,

    /**
     * 注解会在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.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}
  • @Documented

它的作用是能够将注解中的元素包含到 Javadoc 中去。

  • @Inherited

一个被@Inherited注解了的注解修饰了一个父类,如果他的子类没有被其他注解修饰,则它的子类也继承了父类的注解。

2.3 自定义注解(后面讲解)

3. 注解的作用

  • 标记,用于告诉编译器的一些信息
  • 编译时动态处理,如动态生成代码
  • 运行时动态处理,如得到注解信息

4. 自定义注解并解析注解

4.1 自定义注解
  • 使用@interface关键字定义注解
  • 成员以无参无异常的方式声明
  • 可以用default为成员指定默认值
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface AnnoTest {  // 使用@interface关键字定义注解
    //成员以无参无异常的方式声明
    String desc();
    String author();
    
    //可以用default为成员指定默认值
    int age() default 18;
}
4.2 注解的属性类型
  • 基本数据类型
  • String类型
  • 枚举类型
  • 注解类型
  • Class类型
  • 以上类型的数组类型
4.3 使用注解

注解属性赋值:如果注解有多个属性,则可以在注解括号中用“,”号隔开分别给对应的属性赋值

@AnnoTest(desc="annotation class desc", author="annotation class author",age=20)
public class AnnoTestDemo {

    @AnnoTest(desc="annotation method desc", author="annotation method author",age=30)
    public String test() {
        return "test";
    }
}
4.4 解析注解

注:如果我们在定义自己的注解的时候,将@Retention(RetentionPolicy.RUNTIME)改为@Retention(RetentionPolicy.SOURCE)或者@Retention(RetentionPolicy.CLASS),运行上面的程序是不会出现任何结果,因为只有运行时注解可以通过反射获取,其他两种注解在运行时已经被丢弃了。

public static void main(String[] args) {
    try {
        //1、使用类加载器加载类
        Class<?> c = Class.forName("com.anno.AnnoTestDemo");
        //2、找到类上面的注解
        //先判断AnnTestDemo类上面有没有AnnoTest这样的注解
        boolean isExist = c.isAnnotationPresent(AnnoTest.class);
        if (isExist) {
            //3、获取类上的注解实例
            AnnoTest classAnno = (AnnoTest) c.getAnnotation(AnnoTest.class);
            System.out.println(classAnno.author());
        }

        //4、找到方法上的注解
        //拿到给定类所包含的方法
        Method[] methods = c.getDeclaredMethods();
        //遍历方法
        for (Method method : methods) {
            boolean isMExist = method.isAnnotationPresent(AnnoTest.class);
            if (isMExist) {
                //拿到每个方法上的注解
                AnnoTest methodAnno = method.getAnnotation(AnnoTest.class);
                System.out.println(methodAnno.author());
            }
        }

        //另外一种解析方法上注解的方式
        //遍历所有的方法
        for (Method method : methods) {
            //拿到每个方法上的注解
            Annotation[] annotations = method.getAnnotations();
            for (Annotation annotation : annotations) {
                if (annotation instanceof AnnoTest) {
                    AnnoTest methodAnno = (AnnoTest) annotation;
                    System.out.println(methodAnno.author());
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

5. 参考

https://www.jianshu.com/p/9471d6bcf4cf

公共技术点之 Java 注解 Annotation

相关文章

  • 菜鸟学服务端技术----Spirng基础

    注解 Java基础加强总结(一)——注解(Annotation) java中的注解是如何工作的? java 注解 ...

  • 自定义注解

    java annotation基础 java注解分为标准注解和元注解。 标准注解是java为我们提供的预定义的注解...

  • Java注解

    Java注解(Annotation)详解(一)——概述及JDK自带注解 Java注解(Annotation)详解(...

  • 自定义注解实现打印系统日志

    1 注解(Annotation) Java 注解(Annotation)又称 Java 标注,是 JDK5.0 ...

  • Java基础(五)

    Java基础5 JAVA注解 1.注解的使用 定义:注解(Annotation),也叫元数据。一种代码级别的说明。...

  • java基础之注解(annotation)

    前言 从 jdk5开始,Java增加了对元数据的支持,也就是Annotation,Annotation其实就是...

  • java基础之注解(Annotation)

    好久没有写点什么了~。。。 计划记录一下java的注解和反射以及这两个好基友的不可描述,这篇先记录一下注解(Ann...

  • Java基础之注解Annotation

    Java 注解用于为 Java 代码提供元数据。作为元数据,注解并不会直接影响你的代码执行。 1. 注解的定义 注...

  • Java——注解(Annotation)入门学习

    学习资料: Java编程思想 ——第20章 公共技术点之 Java 注解 Annotation 注解(Annota...

  • Java注解(Annotation)详解

    Java注解(Annotation)详解 1.Annotation的概念 An annotation is a f...

网友评论

      本文标题:Java基础之注解Annotation

      本文链接:https://www.haomeiwen.com/subject/gqtpjktx.html