java的注解用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。
注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。
1、元注解
元注解是指注解的注解。包括 @Retention @Target @Document @Inherited四种。
1.1、@Retention: 定义注解的保留策略
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
1.2、@Target:定义注解的作用目标
其定义的源码为:
1 @Documented 2 @Retention(RetentionPolicy.RUNTIME) 3 @Target(ElementType.ANNOTATION_TYPE) 4 public @interface Target { 5 ElementType[] value(); 6 }
@Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
由以上的源码可以知道,他的elementType 可以有多个,一个注解可以为类的,方法的,字段的等等
1.3、@Document:说明该注解将被包含在javadoc中
1.4、@Inherited:说明子类可以继承父类中的该注解
下面是注解的工作原理案例:
1、注解接口:
1 package com.laoxu.test.day01.annotationDemo; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.Target; 6 /** 7 * 注解接口 8 * @author Administrator 9 * 10 */ 11 import java.lang.annotation.RetentionPolicy; 12 @Target({ElementType.TYPE,ElementType.METHOD}) 13 @Retention(RetentionPolicy.RUNTIME) 14 public @interface MyAnnotation { 15 public enum annoType{util,entity,serveice,model};//枚举 16 public annoType classType() default annoType.util; 17 public static final int id = -1; 18 } 19 20 @Retention(RetentionPolicy.RUNTIME) 21 @Target(ElementType.METHOD) 22 @interface HelloWord{ 23 public String name() default ""; 24 }
2、注解工作及测试类:
1 package com.laoxu.test.day01.annotationDemo; 2 3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5 6 import org.apache.commons.lang3.StringUtils; 7 8 import com.laoxu.test.day01.annotationDemo.MyAnnotation.annoType; 9 /** 10 * 通过java的反射机制使用注解 11 * @author Administrator 12 * 13 */ 14 public class AnnotationTest { 15 public static void main(String[] args) throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { 16 ParseAnnotation parseAnnotation = new ParseAnnotation(); 17 parseAnnotation.parseMethod(TestDemo.class); 18 parseAnnotation.parseType(TestDemo.class); 19 20 } 21 } 22 /** 23 * 测试类 24 */ 25 @MyAnnotation 26 class TestDemo { 27 @HelloWord(name = "小米") 28 @MyAnnotation(classType = annoType.serveice) 29 public void getName(String name) { 30 if (StringUtils.isBlank(name)) { 31 System.out.println("say hello word"); 32 } else { 33 System.out.println("this is the test Demo: " + name); 34 } 35 } 36 } 37 /** 38 * 通过反射机制,解析当前类的注解,并将注解参数执行 39 * @author Administrator 40 * 41 */ 42 class ParseAnnotation{ 43 /** 44 * 解析方法的注解 45 * @param clazz 46 * @throws InstantiationException 47 * @throws IllegalAccessException 48 * @throws IllegalArgumentException 49 * @throws InvocationTargetException 50 */ 51 public void parseMethod(Class<?> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{ 52 Object obj = clazz.newInstance(); 53 /* 54 * 通过反射获取操作类的所有方法 55 */ 56 Method[] methods = clazz.getDeclaredMethods(); 57 String name = ""; 58 /* 59 * 遍历方法,将获取注解,并执行参数 60 */ 61 for (Method method : methods) { 62 /* 63 * HelloWord的注解 64 */ 65 HelloWord say = method.getAnnotation(HelloWord.class); 66 if(say!=null){ 67 name = say.name(); 68 method.invoke(obj, name); 69 } 70 /* 71 * MyAnnotation的注解解析 72 */ 73 MyAnnotation anno = method.getAnnotation(MyAnnotation.class); 74 if(anno!=null){ 75 if(MyAnnotation.annoType.util.equals(anno.classType())){ 76 System.out.println("this is a util method"); 77 }else{ 78 System.out.println("this is a : " + anno.classType() + " method"); 79 } 80 }else{ 81 System.out.println("no myannotaion method!"); 82 } 83 } 84 } 85 /** 86 * 解析类的注解 87 * @param clazz 88 */ 89 public void parseType(Class<?> clazz){ 90 MyAnnotation anno = clazz.getAnnotation(MyAnnotation.class); 91 if(anno!=null){ 92 if(MyAnnotation.annoType.util.equals(anno.classType())){ 93 System.out.println("this is a util class"); 94 }else{ 95 System.out.println("this is a : " + anno.classType() + " class"); 96 } 97 }else{ 98 System.out.println("no myannotaion class !"); 99 } 100 } 101 }