• Java 注解(1)注解Annotation的定义,内置注解,元注解


    1.注解概念

    Java 注解可以通过反射获取注解内容。在编译器生成类文件时,注解可以被嵌入到字节码中
    Java 虚拟机可以保留注解内容,在运行时可以获取到注解内容 。 当然它也支持自定义 Java 注解。

    2.Java内置注解

    5 个用于通知编译器信息的注解
    @Override :空注解,用于标记那些覆盖父类方法的方法,如果父类没有这个方法,或者复写的方法访问权限比父类的权限小,编译器就会报错
    @Deprecated : 空注解,用于标记那些不应该被使用的代码,如果使用了过时的代码,编译器会发出警告
    @SafeVarargs : 空注解,(varargs 可变参数)用于标记构造函数或者方法,通知编译器,这里的可变参数相关的操作保证安全
    @FunctionInterface : Java SE 8 出现的,用于通知编译器,这个类型是 function 接口
    @SuppressWarning:抑制错误,可以用于标记整个类、某个方法、某个属性或者某个参数,用于告诉编译器这个代码是安全的,不必警告

    4个作用在注解的注解(元注解)
    @Documented:让注解信息出现在 document 中

    @Retention : 指出注解如何存储,支持以下三种参数

    • RetentionPolicy.SOURCE : 注解只保留在源码中,编译时会忽略
    • RetentionPolicy.CLASS : 更高一级,编译时被编译器保留,但是运行时会被 JVM 忽略
    • RetentionPolicy.RUNTIME : 最高级,运行时会被保留,可以被运行时访问

    @Target :指出注解作用于(修饰)什么对象,支持以下几种参数

    • ElementType.TYPE : 作用于任何类、接口、枚举
    • ElementType.FIELD : 作用于一个域或者属性
    • ElementType.METHOD : 作用于一个方法
    • ElementType.PARAMTER : 作用于参数
    • ElementType.CONSTRUCTOR : 作用于构造函数
    • ElementType.LOCAL_VARIABLE : 作用于本地变量
    • ElementType. ANNOTATION_TYPE : 作用于注解
    • ElementType.PACKAGE : 作用于包

    @Inherited :当前注解是否可以继承

    3.自定义注解

    3.1Java元注解源代码

    首先看看几个典型的Java自带的元注解的源代码是怎么写的:

    • @Override
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface Override {
    }
    

    @interface表示这里定义了一个注解
    @Target(ElementType.METHOD)作用于方法;
    @Retention(RetentionPolicy.SOURCE)表示信息仅存在于编译器处理期间,编译器处理完之后SuppressWarnings就没有作用了。

    • @SuppressWarnings
    @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface SuppressWarnings {
           String[] value();
    }
    

    大部分字段与@Override中类似;
    特别关注下value()这个字段,表示我们在使用@SuppressWarnings时候可以给它传参。
    传参使用示例如下:
    @SuppressWarnings("unchecked")
    告诉编译器忽略 unchecked 警告信息,如使用List,ArrayList等未进行参数化产生的警告信息。
    @SuppressWarnings("serial")
    如果编译器出现这样的警告信息:The serializable class WmailCalendar does notdeclare a static final serialVersionUID field of type long使用这个注释将警告信息去掉。
    @SuppressWarnings("deprecation")
    如果使用了使用@Deprecated注释的方法,编译器将出现警告信息。使用这个注释将警告信息去掉。
    @SuppressWarnings("unchecked", "deprecation")
    告诉编译器同时忽略unchecked和deprecation的警告信息。
    @SuppressWarnings(value={"unchecked", "deprecation"})
    等同于@SuppressWarnings("unchecked", "deprecation")

    3.2自定义注解

    注解的通用定义方法是,使用@interface语法。
    比如自定义一个简单的注解MyAnnotation1:需要采用@interface标识,并辅以元注解进行标注,并且自己去实现注解的具体业务解释代码

    @Documented
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation1 {
    }
    

    在元注解的源代码中,比如@Override,可以看到并没有具体处理逻辑,它只是一个修饰作用,告诉编译器这个方法要覆盖父类的方法,编译器会去检查父类有没有这个方法。
    原因:元注解是由注解编译器实现了业务逻辑代码(在java代码里无法看到实现,应该是在编译器里有具体的实现)。

    下面是一个完整的自定义注解,包括其与反射结合的使用示例
    Annotation在反射函数中的使用示例

    package JavaAdvancedCharateristic.Annotation;
    
    import java.lang.annotation.Annotation;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.reflect.Method;
    
    //用@interface,自定义一个注解
    @Retention(RetentionPolicy.RUNTIME)
    @interface MyAnnotation {
        String[] value() default "unknown";//如果不传参,则采用参数的默认值unknown
    }
    
    /**
     * Person类。它会使用MyAnnotation注解。
     */
    class Person {
    
        /**
         * empty()方法同时被 "@Deprecated" 和 “@MyAnnotation(value={"a","b"})”所标注
         * (01) @Deprecated,意味着empty()方法,不再被建议使用
         * (02) @MyAnnotation, 意味着empty() 方法对应的MyAnnotation的value值是默认值"unknown"
         */
        @MyAnnotation
        @Deprecated
        public void empty() {
            System.out.println("
    empty");
        }
    
        /**
         * sombody() 被 @MyAnnotation(value={"girl","boy"}) 所标注,
         *
         * @MyAnnotation(value={"girl","boy"}), 意味着MyAnnotation的value值是{"girl","boy"}
         */
        @MyAnnotation(value = {"girl", "boy"})
        public void somebody(String name, int age) {
            System.out.println("
    somebody: " + name + ", " + age);
        }
    }
    
    public class AnnotationTest {
    
        public static void main(String[] args) throws Exception {
    
            // 新建Person
            Person person = new Person();
            // 获取Person的Class实例
            Class<Person> c = Person.class;
            // 获取 somebody() 方法的Method实例
            Method mSomebody = c.getMethod("somebody", new Class[]{String.class, int.class});
            // 执行该方法
            mSomebody.invoke(person, new Object[]{"lily", 18});
            iteratorAnnotations(mSomebody);
    
    
            // 获取 somebody() 方法的Method实例
            Method mEmpty = c.getMethod("empty", new Class[]{});
            // 执行该方法
            mEmpty.invoke(person, new Object[]{});
            iteratorAnnotations(mEmpty);
        }
    
        public static void iteratorAnnotations(Method method) {
    
            // 判断 somebody() 方法是否包含MyAnnotation注解
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                // 获取该方法的MyAnnotation注解实例
                MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
                // 获取 myAnnotation的值,并打印出来
                String[] values = myAnnotation.value();
                for (String str : values)
                    System.out.printf(str + ", ");
                System.out.println();
            }
    
            // 获取方法上的所有注解,并打印出来
            Annotation[] annotations = method.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println(annotation);
            }
        }
    }
    
    

    运行结果:
    运行结果:
    somebody: lily, 18
    girl, boy,
    @com.skywang.annotation.MyAnnotation(value=[girl, boy])

    empty
    unknown,
    @com.skywang.annotation.MyAnnotation(value=[unknown])
    @java.lang.Deprecated()

  • 相关阅读:
    数据结构和算法
    Java Zip工具类(全)
    Java Zip压缩文件返回前端并下载
    Java 通过URL进行远程文件下载
    最通俗易懂的JavaScript实用案例
    通俗易懂的JavaScript进阶教程
    最通俗易懂的JavaScript入门教程
    Git和Github详细入门教程(别再跟我说你不会Git和Github)
    HTML入门详细总结
    你好,我是梦阳辰!
  • 原文地址:https://www.cnblogs.com/JohnTeslaaa/p/12713577.html
Copyright © 2020-2023  润新知