標籤: javahtml
[TOC]java
註解(Annotation),也叫元數據。一種代碼級別的說明。它是JDK1.5及之後版本引入的一個特性,與類、接口、枚舉是在同一個層次。它能夠聲明在包、類、字段、方法、局部變量、方法參數等的前面,用來對這些元素進行說明,註釋。git
APIgithub
調用/結構關係:A<--B<--C數組
A,B,C解釋以下:oracle
A:註解類工具
@interface A{ }
B:應用了「註解類」的類網站
@A Class B{ }
C:對「應用了註解類的類」進行反射操做的類.net
Class C{ public void f(){ B.class.isAnnotationPresent(A.class); A a = B.class.getAnnotion(A.class); } }
元註解的做用就是負責註解其餘註解。四個元註解分別是:@Target,@Retention,@Documented,@Inherited
@Retention
表示在什麼級別保存該註解信息。可選的參數值在枚舉類型 RetentionPolicy
中,包括RetentionPolicy.SOURCE
,RetentionPolicy.CLASS
(默認),RetentionPolicy.RUNTIME
分別對應:java源文件-->class文件-->內存中的字節碼
RetentionPolicy.SOURCE 註解將被編譯器丟棄 RetentionPolicy.CLASS 註解在class文件中可用,但會被VM丟棄 RetentionPolicy.RUNTIME VM將在運行期也保留註釋,所以能夠經過反射機制讀取註解的信息。
@Target
表示該註解用於什麼地方,可能的值在枚舉類ElemenetType
中,包括
ElemenetType.CONSTRUCTOR 構造器聲明 ElemenetType.FIELD 域聲明(包括 enum 實例) ElemenetType.LOCAL_VARIABLE 局部變量聲明 ElemenetType.METHOD 方法聲明 ElemenetType.PACKAGE 包聲明 ElemenetType.PARAMETER 參數聲明 ElemenetType.TYPE 類,接口(包括註解類型)或enum聲明
@Documented
將此註解包含在javadoc中 ,它表明着此註解會被javadoc工具提取成文檔。在doc文檔中的內容會由於此註解的信息內容不一樣而不一樣。至關於@see,@param
等
@Inherited
容許子類繼承父類中的註解
使用@interface
自定義註解時,自動繼承了java.lang.annotation.Annotation
接口,由編譯程序自動完成其餘細節。在定義註解時,不能繼承其餘的註解或接口。@interface
用來聲明一個註解,其中的每個方法其實是聲明瞭一個配置參數。方法的名稱就是參數的名稱,返回值類型就是參數的類型(返回值類型只能是基本類型、Class、String、enum)。能夠經過default來聲明參數的默認值。
定義註解格式:
public @interface 註解名 {定義體}
註解參數的可支持數據類型:
1.全部基本數據類型(int,float,boolean,byte,double,char,long,short) 2.String類型 3.Class類型 4.enum類型 5.Annotation類型 6.以上全部類型的數組
參考文末的【參考資料】中《java 註解的幾大做用及使用方法詳解(完)》
下面的示例,是上文提到的A<--B<--C的擴充版本。自定義了一個註解@A
,而後在B類中使用了註解@A
,最後在類C中利用反射讀取@A
中的信息
A.java
package com.iot.annotation; import java.lang.annotation.*; /** * Created by brian on 2016/2/20. */ @Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD,ElementType.CONSTRUCTOR}) @Retention(RetentionPolicy.RUNTIME) public @interface A { String name(); int id() default 0; Class<Long> gid(); }
B.java
package com.iot.annotation; import java.util.HashMap; import java.util.Map; /** * Created by brian on 2016/2/20. */ @A(name="type",gid=Long.class)//類註解 public class B { @A(name="param",id=1,gid=Long.class) //類成員註解 private Integer age; @A(name="construct",id=2,gid=Long.class) //構造方法註解 public B(){} @A(name="public method",id=3,gid=Long.class) //類方法註解 public void a(){ } @A(name="protected method",id=4,gid=Long.class) //類方法註解 protected void b(){ Map<String,String> m = new HashMap<String,String>(0); } @A(name="private method",id=5,gid=Long.class) //類方法註解 private void c(){ Map<String,String> m = new HashMap<String,String>(0); } public void b(Integer a){ } }
C.java
package com.iot.annotation; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** * Created by brian on 2016/2/20. */ public class C { /** * 簡單打印出B類中所使用到的類註解 * 該方法只打印了 Type 類型的註解 * @throws ClassNotFoundException */ public static void parseTypeAnnotation() throws ClassNotFoundException{ Class clazz = Class.forName("com.iot.annotation.B"); Annotation[] annotations = clazz.getAnnotations(); for(Annotation annotation :annotations){ A a = (A)annotation; System.out.println("id = "+a.id()+" ;name = "+a.name()+" ;gid = "+a.gid()); } } /** * 簡單打印出B類中所使用到的方法註解 * 該方法只打印了 Method 類型的註解 */ public static void parseMethodAnnotation() { Method[] methods = B.class.getDeclaredMethods(); for (Method method : methods) { /* * 判斷方法中是否有指定註解類型的註解 */ boolean hasAnnotation = method.isAnnotationPresent(A.class); if (hasAnnotation) { /* * 根據註解類型返回方法的指定類型註解 */ A annotation = method.getAnnotation(A.class); System.out.println("method = " + method.getName() + " ; id = " + annotation.id() + " ; description = " + annotation.name() + "; gid= " + annotation.gid()); } } } /** * 簡單打印出B類中所使用到的方法註解 * 該方法只打印了 Method 類型的註解 */ public static void parseConstructAnnotation(){ Constructor[] constructors = B.class.getConstructors(); for (Constructor constructor : constructors) { /* * 判斷構造方法中是否有指定註解類型的註解 */ boolean hasAnnotation = constructor.isAnnotationPresent(A.class); if (hasAnnotation) { /* * 根據註解類型返回方法的指定類型註解 */ A annotation =(A) constructor.getAnnotation(A.class); System.out.println("constructor = " + constructor.getName() + " ; id = " + annotation.id() + " ; description = " + annotation.name() + "; gid= "+annotation.gid()); } } } public static void main(String[] args) throws ClassNotFoundException { parseTypeAnnotation(); parseMethodAnnotation(); parseConstructAnnotation(); } }