Java Annotations是什么
- Annontation是Java5開始引入的新特征。中文名稱一般叫注解伯复。它提供了一種安全的類似注釋的機制樱报,用來將任何的信息或元數(shù)據(jù)(metadata)與程序元素(類阵面、方法、成員變量等)進行關(guān)聯(lián)誊涯。
- 更通俗的意思是為程序的元素(類挡毅、方法、成員變量)加上更直觀更明了的說明暴构,這些說明信息是與程序的業(yè)務(wù)邏輯無關(guān)跪呈,并且是供指定的工具或框架使用的。
- Annontation像一種修飾符一樣取逾,應(yīng)用于包耗绿、類型、構(gòu)造方法砾隅、方法误阻、成員變量、參數(shù)及本地變量的聲明語句中晴埂。
簡單示例
- 下面通過一個簡單的例子來看一下Java Annotations 的用法究反。例子里面有兩個Annotations定義,一個使用Annotations的類儒洛。一個解析Annotations的類精耐。
Annotations定義1:一個面向類型的說明
package annoation.test;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by haicheng.lhc on 04/07/2017.
*
* @author haicheng.lhc
* @date 2017/07/04
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface Description {
String value();
}
Annotations定義12:一個面向方法的說明
package annoation.test;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
/**
* Created by haicheng.lhc on 04/07/2017.
*
* @author haicheng.lhc
* @date 2017/07/04
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Author {
String name();
String group();
}
使用Annotations的類
package annoation.test;
/**
* Created by haicheng.lhc on 04/07/2017.
*
* @author haicheng.lhc
* @date 2017/07/04
*/
@Description(value = "這是一個有用的類")
public class Utility {
@Author(name = "haoran_202",group="com.magc")
public String work() {
return "work over!";
}
}
解析Annotations的類
package annoation.test;
import java.lang.reflect.Method;
/**
* Created by haicheng.lhc on 04/07/2017.
*
* @author haicheng.lhc
* @date 2017/07/04
*/
public class AnalysisAnnotation {
public static void main(String[] args) {
try {
//通過運行時反射API獲得annotation信息
Class rt_class = Class.forName("annoation.test.Utility");
Method[] methods = rt_class.getMethods();
boolean flag = rt_class.isAnnotationPresent(Description.class);
if (flag) {
Description description = (Description)rt_class.getAnnotation(Description.class);
System.out.println("Utility's Description--->" + description.value());
for (Method method : methods) {
if (method.isAnnotationPresent(Author.class)) {
Author author = (Author)method.getAnnotation(Author.class);
System.out.println("Utility's Author--->" + author.name() + " from " + author.group());
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
輸出結(jié)果
深入分析
Annotation 組成
每一個Annotation有三部分組成:
- 1、Annotation.java
定義中的@Interface就代表該類繼承了Annotation
package java.lang.annotation;
public interface Annotation {
boolean equals(Object obj);
int hashCode();
String toString();
Class<? extends Annotation> annotationType();
}
- 2琅锻、ElementType.java
package java.lang.annotation;
public enum ElementType {
TYPE, /* 類卦停、接口(包括注釋類型)或枚舉聲明 */
FIELD, /* 字段聲明(包括枚舉常量) */
METHOD, /* 方法聲明 */
PARAMETER, /* 參數(shù)聲明 */
CONSTRUCTOR, /* 構(gòu)造方法聲明 */
LOCAL_VARIABLE, /* 局部變量聲明 */
ANNOTATION_TYPE, /* 注釋類型聲明 */
PACKAGE /* 包聲明 */
}
- 3、RetentionPolicy.java
package java.lang.annotation;
public enum RetentionPolicy {
SOURCE, /* Annotation信息僅存在于編譯器處理期間恼蓬,編譯器處理完之后就沒有該Annotation信息了 */
CLASS, /* 編譯器將Annotation存儲于類對應(yīng)的.class文件中沫浆。默認行為 */
RUNTIME /* 編譯器將Annotation存儲于class文件中,并且可由JVM讀入 */
}
如何定義
Annotation類型使用關(guān)鍵字@interface而不是interface滚秩,這個關(guān)鍵字聲明隱含了一個信息:它是繼承了java.lang.annotation.Annotation接口,并非聲明了一個interface
Annotation類型淮捆、方法定義是獨特的郁油、受限制的
1本股、Annotation 類型的方法必須聲明為無參數(shù)、無異常拋出的桐腌。
2拄显、這些方法定義了annotation的成員:方法名成為了成員名,而方法返回值成為了成員的類型案站。
3躬审、而方法返回值類型必須為primitive類型、Class類型蟆盐、枚舉類型承边、annotation類型或者由前面類型之一作為元素的一維數(shù)組。
4、方法的后面可以使用 default和一個默認數(shù)值來聲明成員的默認值,null不能作為成員默認值任连,這與我們在非annotation類型中定義方法有很大不同拨黔。
5、Annotation類型和它的方法不能使用annotation類型的參數(shù)呛哟、成員不能是generic。
6、只有返回值類型是Class的方法可以在annotation類型中使用generic窖式,因為此方法能夠用類轉(zhuǎn)換將各種類型轉(zhuǎn)換為Class。