• java基础源码 (3)--Annotation(注解)


    借鉴博客地址:https://www.cnblogs.com/skywang12345/p/3344137.html

    /**
     * The common interface extended by all annotation types. 
     所有注释类型扩展的公共接口*/
    public interface Annotation {
      
        boolean equals(Object obj);
    
        /**
         * Returns the hash code of this annotation, as defined below:
        返回注解的哈希码值*/
        int hashCode();
    
        /**
         * Returns a string representation of this annotation.  The details
         * of the representation are implementation-dependent, but the following
         * may be regarded as typical:
        以字符串形式返回注解
    */ String toString(); /** * Returns the annotation type of this annotation.    返回注解的类型*/ Class<? extends Annotation> annotationType(); }
    ElementType.java是Enum枚举类型,它用来指定Annotation的类型
    /**
    * The constants of this enumerated type provide a simple classification of the * syntactic locations where annotations may appear in a Java program. These * constants are used in {@link Target java.lang.annotation.Target} * meta-annotations to specify where it is legal to write annotations of a * given type.   此枚举类型的常量提供了可能出现在java程序中注释的位置进行简单分类,这些类型是用于Targer(元注释)上
    *此枚举类型的常量提供了注释可能出现在Java程序中的语法位置的简单分类。 这些常量用于{@link Target java.lang.annotation.Target}元注释,以指定编写给定类型注释的合法位置。
    */ 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 }

    RetentionPolicy.java,是Enum枚举类型,它用来指定Annotation的策略。通俗点说,就说不同的RetentionPolicy的注释作用域不同

    /**
     * Annotation retention policy.
     注释保留策略*/
    public enum RetentionPolicy {
        /**
         * Annotations are to be discarded by the compiler.
        Annotation注释信息仅存在于编译器处理期间,编译器处理完成之后就没有改注释信息了
    */ 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.
        编译器将Annotation注释存储于类对应的在.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.   编译器将Annotation存储于类对应的。class文件中,并且可以由JVM读入(反射)*/ RUNTIME }

    语法定义:

      

    /*
    * @interface:
    *    意味着它实现了java.lang.annotation.Annotation接口,即该注解就是一个Annotation
    *    定义Annotation时,@interface是必须的
    *    注意:
    *       它和我们通常的implemented实现接口的方法不同,Annotation接口的实现细节都由编译器
    *       完成。通过@interface定义注解后,改注解不能继承其他的注解或接口
    * @Documented:
    *    类和方法的Annotation在缺省情况下是不出现在javadoc中的,如果使用@Documented修饰该注解
    *    则表示它可以出现在Javadoc中。定义注解时,@Documented可有可无,若没有定义,则注解不会
    *    出现在javadoc中
    * @Target(ElementType.TYPE):
    *    ElementType是Annotation(注解)的类型属性,而@Target的作用,就是来指定Annotation(注解)
    *    类型属性。@Target(ElementType.TYPE)指定该Annotation(注解)的类型是ElementType.TYPE,
    *    这意味着MyAnnotation是用来修饰类,接口(包括注释类型)或枚举声明的注释。定义Annotation(注解)
    *    时,@Target可有可无,若有@Target,则该Annotation(注解)可以用于任何地方
    *@Retention(RetentionPolicy.RUNTIME):
    *    RetentionPolicy是Annotation(注解)的策略属性,而@Retention的作用,就是指定Annotation(注解)
    *    的策略是RetentionPolicy.RUNTIME,意味着,编译器会将该Annotation信息保存在对应类的.class文件中
    *    并且能被jvm读取。定义Annotation(注解)时,@Retention可有可无,若没有@Retention,则默认是
    *    RetentionPolicy.CLASS(默认行为)
    * */
    @Documented
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation {
    
    }

    反射使用注解

    package com.lkj.Annotation;
    
    import com.lkj.string.Persion;
    
    import java.lang.annotation.*;
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
    
    
    @Retention(RetentionPolicy.RUNTIME)
    @interface MyAnnotation2{
        String [] value() default "unknown";
    }
    
    class Person{
        @MyAnnotation2//意味着empty()对应的MyAnnotation2的value值默认是unknown
        @Deprecated//意味着empty()方法,不再被建议使用
        public void empty(){
            System.out.println("
    empty");
        }
        @MyAnnotation2(value = {"girl","boy"})//意味着MyAnnotation2的value值是{“girl”,“boy”}
        public void someBody(String name,int age){
            System.out.println("
    somebody: "+name+", "+age);
        }
    }
    
    public class AnnotationUser  {
        public static void iteratorAnnotations(Method method){
            //判断someBody()方法是否包含MyAnnotation2注解
            if(method.isAnnotationPresent(MyAnnotation2.class)){
                //获取该方法的MyAnnotation2注解实例
                MyAnnotation2 myAnnotation2 = method.getAnnotation(MyAnnotation2.class);
                //获取MyAnnotation2的值,并打印出来
                String[] value = myAnnotation2.value();
                for (int i=0;i<value.length;i++){
                    System.out.printf(value[i]);
                }
                System.out.println();
            }
            //获取方法上的所有注解,并打印出来
            Annotation[] annotations = method.getAnnotations();
            for (Annotation annotation:annotations){
                System.out.println(annotation);
            }
        }
        public static void main(String []args) throws Exception {
            //实例Persion对象
            Person person = new Person();
            //获取Persion的Class实例
            Class<Person> c=Person.class;
            //获取someBody()方法的method实例
            Method method=c.getMethod("someBody", new Class[]{String.class,int.class});
            //执行该方法
            method.invoke(person,new Object[]{"lily",18});
            iteratorAnnotations(method);
    
            //获取someBody()方法的Method实例
            Method empty = c.getMethod("empty", new Class[]{});
            empty.invoke(person,new Object[]{});
            iteratorAnnotations(empty);
        }
    }

    输出结果:

      

  • 相关阅读:
    python 一个二维数组和一个整数,判断数组中是否含有该整数
    DDD 全称 “Domain-Driven Design”,领域驱动设计
    pytest + allure 生成测试报告
    AttributeError: module 'pytest' has no attribute 'allure'
    BDD的概念
    在im4java中使用GraphicsMagick
    缓存穿透与缓存雪崩
    Linux安装ImageMagick与JMagick完成过程及配置
    Windows/Linux下引用jar包,并用javac/java编译运行
    在CentOS4上安装JMagick
  • 原文地址:https://www.cnblogs.com/lkeji388/p/9518468.html
Copyright © 2020-2023  润新知