借鉴博客地址: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); } }
输出结果: