Java注解定義
注解(Annotation),也叫元數(shù)據(jù)。一種代碼級(jí)別的說(shuō)明。它是JDK1.5及以后版本引入的一個(gè)特性,與類(lèi)、接口、枚舉是在同一個(gè)層次。它可以聲明在包、類(lèi)、字段、方法、局部變量、方法參數(shù)等的前面,用來(lái)對(duì)這些元素進(jìn)行說(shuō)明,注釋。
Java注解作用
1、編寫(xiě)文檔:通過(guò)代碼里標(biāo)識(shí)的元數(shù)據(jù)生成文檔【生成文檔doc文檔】
2、代碼分析:通過(guò)代碼里標(biāo)識(shí)的元數(shù)據(jù)對(duì)代碼進(jìn)行分析【使用反射】
3、編譯檢查:通過(guò)代碼里標(biāo)識(shí)的元數(shù)據(jù)讓編譯器能夠?qū)崿F(xiàn)基本的編譯檢查【Override】
Java注解分類(lèi)
1、內(nèi)置的作用在代碼的注解
- @Override - 檢查該方法是否是重寫(xiě)方法。如果發(fā)現(xiàn)其父類(lèi),或者是引用的接口中并沒(méi)有該方法時(shí),會(huì)報(bào)編譯錯(cuò)誤。
- @Deprecated - 標(biāo)記過(guò)時(shí)方法。如果使用該方法,會(huì)報(bào)編譯錯(cuò)誤。
- @SuppressWarnings - 指示編譯器去忽略注釋中聲明的警告。
2、內(nèi)置的作用在其它注解上的注解(原注解) - @Retention - 標(biāo)示這個(gè)注解怎么保存,是只在代碼中,還是編入class文件中,或者是在運(yùn)行時(shí)可以通過(guò)反射訪問(wèn)。
- @Documented - 標(biāo)記這些注釋是否包含在用戶(hù)文檔中。
- @Target - 表示這個(gè)注釋的作用范圍
- @Inherited - 標(biāo)示注釋可被繼承類(lèi)獲取
3、從Java7開(kāi)始,額外添加了3個(gè)注釋?zhuān)?/li> - @SafeVarargs - Java7開(kāi)始支持,忽略任何使用參數(shù)為范型變量的方法或構(gòu)造函數(shù)調(diào)用產(chǎn)生的警告。
- @Functionallnterface - Java8開(kāi)始支持,標(biāo)識(shí)一個(gè)匿名函數(shù)或函數(shù)式接口。
- @Repeatable - Java8開(kāi)始支持,標(biāo)識(shí)某注解可以在同一個(gè)聲明上使用多次
Annotation組成部分
java Annotation的組成中,有3個(gè)非常重要的主干類(lèi)。它們分別是:
- Annotation.java
public interface Annotation {
/**
* @return true if the specified object represents an annotation
*/
boolean equals(Object obj);
/**
* @return the hash code of this annotation
*/
int hashCode();
/**
* @return a string representation of this annotation
*/
String toString();
/**
* @return the annotation type of this annotation
*/
Class<? extends Annotation> annotationType();
}
- ElementType.java
public enum ElementType {
/** 類(lèi)、接口(包括注釋類(lèi)型)或枚舉聲明*/
TYPE,
/** 字段聲明(包括枚舉常量)*/
FIELD,
/** 方法聲明 */
METHOD,
/** 正式的參數(shù)聲明 */
PARAMETER,
/** 構(gòu)造函數(shù)聲明 */
CONSTRUCTOR,
/** 本地變量聲明*/
LOCAL_VARIABLE,
/** 注釋類(lèi)型聲明 */
ANNOTATION_TYPE,
/** 包聲明 */
PACKAGE,
/**
* 類(lèi)型參數(shù)聲明
* @since 1.8
*/
TYPE_PARAMETER,
/**
* 字體的使用
* @since 1.8
*/
TYPE_USE
}
- RetentionPolicy.java
public enum RetentionPolicy {
/*注釋將被編譯器丟棄*/
SOURCE,
/**
* 注釋由編譯器記錄在類(lèi)文件中
* 但不需要在運(yùn)行時(shí)被VM保留。這是默認(rèn)設(shè)置
*/
CLASS,
/**
* 注釋由編譯器和記錄在類(lèi)文件中
* 在運(yùn)行時(shí)被VM保留,因此它們可以被反射式讀取。
*/
RUNTIME
}
自定義注釋
//元注釋
public @interface 注釋名稱(chēng){
// 屬性列表
}
1、創(chuàng)建一個(gè)注釋
@Deprecated //是否為過(guò)期方法
@Documented //標(biāo)記這些注釋是否包含在用戶(hù)文檔中
@Retention(RetentionPolicy.RUNTIME)//注釋怎么保存
@Target(ElementType.METHOD)//注釋用在哪里
@Inherited //注釋是否可以被繼承
public @interface TestAnnotation {
String value();
}
2、創(chuàng)建一個(gè)使用注釋的類(lèi)
public class HelloAnnotationClient {
@TestAnnotation("matthew")
public void sayHello() {
System.out.println("Inside sayHello method...");
}
}
3、通過(guò)反射獲取方法及注釋攜帶的信息注意,如果要攜帶信息能在運(yùn)行時(shí)被反射獲取需要設(shè)置@Retention(RetentionPolicy.RUNTIME)
public class HelloAnnotationTest {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
HelloAnnotationClient helloAnnotationClient = new HelloAnnotationClient();
Method method = helloAnnotationClient.getClass().getMethod("sayHello");
if (method.isAnnotationPresent(TestAnnotation.class)) {
TestAnnotation annotation = method.getAnnotation(TestAnnotation.class);
System.out.println("Value:"+annotation.value());
method.invoke(helloAnnotationClient);
}
}
}
4、運(yùn)行的結(jié)果
Value:matthew
Inside sayHello method...
Process finished with exit code 0