java注解概念
Java提供了一種原程序中的元素關聯任何信息和任何數據的途徑和方法
java注解介紹
常用注解
@Override:表示方法是重寫的方法
@Deprecated:過時的方法
@SuppressWarnings:抑制警告
注解分類
按照運行機制分
1、源碼注解:注解只在源碼中存在,編譯成.class文件就不存在了
2、編譯時注解:注解在源碼和.class文件中都存在,如@Override
3、運行時注解:在運行階段起作用,甚至會影響運行邏輯,如@Autowired
按照來源分
1、JDK自帶注解
2、第三方注解
3、自定義注解
自定義注解和使用
1、使用@interface關鍵定義注解(Description.java),如下:
1 package com.hd; 2 3 import java.lang.annotation.Documented; 4 import java.lang.annotation.ElementType; 5 import java.lang.annotation.Inherited; 6 import java.lang.annotation.Retention; 7 import java.lang.annotation.RetentionPolicy; 8 import java.lang.annotation.Target; 9 10 /** 11 * 注解的注解:元注解 12 * 13 * 注解作用域 14 ElementType.TYPE:允許被修飾的注解作用在類、接口和枚舉上 15 ElementType.FIELD:允許作用在屬性字段上 16 ElementType.METHOD:允許作用在方法上 17 ElementType.PARAMETER:允許作用在方法參數上 18 ElementType.CONSTRUCTOR:允許作用在構造器上 19 ElementType.LOCAL_VARIABLE:允許作用在本地局部變量上 20 ElementType.ANNOTATION_TYPE:允許作用在注解上 21 ElementType.PACKAGE:允許作用在包上 22 23 注解的生命周期 24 RetentionPolicy.SOURCE:當前注解編譯期可見,不會寫入 class 文件 25 RetentionPolicy.CLASS:類加載階段丟棄,會寫入 class 文件 26 RetentionPolicy.RUNTIME:永久保存,可以反射獲取 27 * 28 */ 29 // 注解的作用域 30 @Target({ElementType.METHOD, ElementType.TYPE}) 31 // 注解的生命周期 32 @Retention(RetentionPolicy.RUNTIME) 33 // 允許子類繼承 34 @Inherited 35 // 生成javadoc的時候生成注解的信息 36 @Documented 37 // @interface:使用@interface關鍵定義注解 38 public @interface Description { 39 40 // 注解的成員 41 // 成員類型所限的,合法的類型包括原始數據類型及String、Class、Annotation、Enumeration 42 String desc(); 43 44 String author(); 45 46 // 成員以無參無異常方式生命,可以用default為成員指定一個默認值 47 int age() default 18; 48 49 // 如果注解成員只有一個時,成員名必須取名未value(),在使用時可以忽略成員名和賦值號(=) 50 // 注解可以沒有成員,沒有成員的注解成為標識注解 51 }
2、在普通類上使用注解,使用方法
注解使用: @<注解名>(<成員名1>=<成員值1>, <成員名2>=<成員值2>, ...)
如下:
1 package com.hd; 2 3 /** 4 * 注解使用: 5 * @<注解名>(<成員名1>=<成員值1>, <成員名2>=<成員值2>, ...) 6 * @author H__D 7 * @date 2019-07-09 22:49:32 8 * 9 */ 10 @Description(desc="I am class annotation", author="hd") 11 public class TestDescription { 12 13 @Description(desc="I am method annotation", author="hd") 14 public String test(){ 15 16 return "red"; 17 } 18 19 20 }
3、解析注解,通過反射獲取類,函數或成員上的運行時注解信息,從而實現動態控制程序運行的邏輯
1 package com.hd; 2 3 import java.lang.annotation.Annotation; 4 import java.lang.reflect.Method; 5 6 /** 7 * 解析注解 8 * 通過反射獲取類,函數或成員上的運行時注解信息,從而實現動態控制程序運行的邏輯 9 * 10 * 對於一個類或者接口來說,Class 類中提供了以下一些方法用於反射注解。 11 getAnnotation:返回指定的注解 12 isAnnotationPresent:判定當前元素是否被指定注解修飾 13 getAnnotations:返回所有的注解 14 getDeclaredAnnotation:返回本元素的指定注解 15 getDeclaredAnnotations:返回本元素的所有注解,不包含父類繼承而來的 16 * 17 * @author H__D 18 * @date 2019-07-09 22:52:42 19 * 20 */ 21 public class ParseDecription { 22 23 public static void main(String[] args) { 24 // TODO Auto-generated method stub 25 // 1、使用類加載器加載類 26 try { 27 Class c = Class.forName("com.hd.TestDescription"); 28 System.out.println(c); 29 30 // 2、找到類上面的注解 31 boolean isExist = c.isAnnotationPresent(Description.class); 32 33 if(isExist) { 34 // 3、拿到注解實例 35 Description d = (Description) c.getAnnotation(Description.class); 36 System.out.println("========parse class annotation========="); 37 System.out.println("desc = " + d.desc()); 38 System.out.println("author = " + d.author()); 39 System.out.println("age = " + d.age()); 40 } 41 42 // 4、找到方法上的注解 43 Method[] ms = c.getMethods(); 44 for (Method m : ms) { 45 boolean isMExist = m.isAnnotationPresent(Description.class); 46 if(isMExist) { 47 Description d = m.getAnnotation(Description.class); 48 System.out.println("========parse method annotation========="); 49 System.out.println("desc = " + d.desc()); 50 System.out.println("author = " + d.author()); 51 System.out.println("age = " + d.age()); 52 } 53 } 54 55 // 另外一種解析方法 56 for (Method m : ms) { 57 Annotation[] annotations = m.getAnnotations(); 58 for (Annotation annotation : annotations) { 59 if(annotation instanceof Description) { 60 System.out.println("========parse method annotation other way========="); 61 Description d = (Description) annotation; 62 System.out.println("desc = " + d.desc()); 63 System.out.println("author = " + d.author()); 64 System.out.println("age = " + d.age()); 65 } 66 } 67 } 68 69 } catch (ClassNotFoundException e) { 70 // TODO Auto-generated catch block 71 e.printStackTrace(); 72 } 73 } 74 }
4、運行結果如下: