JAVA基礎(chǔ)--注解(Annotation)
JAVA基礎(chǔ)--注解(Annotation)
一、概念
注解:提供一種為程序提供元數(shù)據(jù)(metadata)的方法
基本原則:注解不能直接干擾程序代碼的運(yùn)行,無(wú)論刪除還是增加注解,代碼都能夠正常運(yùn)行。
注解元素?cái)?shù)據(jù)類型:
- 所有基本類型
- String
- Class
- enum
- Annotation
- 以上類型的數(shù)組
應(yīng)用:
1、編寫(xiě)文檔:通過(guò)代碼里標(biāo)識(shí)的元數(shù)據(jù)生成文檔
2、代碼分析:通過(guò)代碼里標(biāo)識(shí)的元數(shù)據(jù)對(duì)代碼進(jìn)行分析
3、編譯檢查:通過(guò)代碼里標(biāo)識(shí)的元數(shù)據(jù)讓編譯器能進(jìn)行基本的編譯檢查,如@Override
二、標(biāo)準(zhǔn)注解
@Override
保證編譯時(shí)候Override函數(shù)的申明正確性
@Deprecated
標(biāo)記過(guò)時(shí)方法,如果使用該注解,編譯時(shí)會(huì)報(bào)編譯警告
與javadoc里的@deprecated有相同的功能,準(zhǔn)確的說(shuō)它還不如@deprecated,因?yàn)樗恢С謪?shù)
@SuppressWarnings
關(guān)閉特定的警告信息
@SuppressWarnings(value={"unchecked", "rawtypes"})
class Test{
@SuppressWarnings("unchecked")
public void testMethod(){
@SuppressWarnings("rawtypes")
List list = new ArrayList();
}
}
常見(jiàn)參數(shù):
| 參數(shù) | 含義 |
|---|---|
| deprecation | 關(guān)閉使用了過(guò)時(shí)的類或方法時(shí)的警告 |
| unchecked | 關(guān)閉執(zhí)行了未檢查的轉(zhuǎn)換時(shí)的警告 |
| fallthrough | 關(guān)閉當(dāng)switch程序塊直接進(jìn)入下一情況而未break的警告 |
| path | 關(guān)閉在類路徑、源文件路徑等中有不存在的路徑時(shí)的警告 |
| serial | 關(guān)閉當(dāng)在可序列化的類上缺少 serialVersionUID 定義時(shí)的警告 |
| finally | 關(guān)閉任何finally子句不能正常完成時(shí)的警告 |
| all | 關(guān)閉關(guān)于以上所有情況的警告 |
@FunctionalInterface
java8支持,標(biāo)識(shí)一個(gè)匿名函數(shù)或函數(shù)式接口
函數(shù)式接口(Functional Interface)就是有且僅有一個(gè)抽象方法,但有多個(gè)非抽象方法的接口。
三、元注解
負(fù)責(zé)注解其他的注解
@Retention
表示需要在什么級(jí)別保存該注解信息
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
RetentionPolicy是一個(gè)枚舉類型,它定義了被@Retention修飾的注解所支持的保留級(jí)別
| 生命周期類型 | 描述 |
|---|---|
| RetentionPolicy.SOURCE | 編譯時(shí)被丟棄,不包含在類文件中 |
| RetentionPolicy.CLASS | JVM加載時(shí)被丟棄,包含在類文件中,默認(rèn)值 |
| RetentionPolicy.RUNTIME | 由JVM加載,包含在類文件中,在運(yùn)行時(shí)可以被獲取到 |
@Target
該注解可以用于什么地方,指定作用域
源碼:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
ElementType是一個(gè)枚舉類型,它定義了被@Target修飾的注解可以作用的范圍
| Target類型 | 作用 |
|---|---|
| TYPE | 類、接口(包括注解類型)、枚舉 |
| FIELD | 字段或?qū)傩裕ò杜e) |
| METHOD | 方法函數(shù) |
| PARAMETER | 方法的參數(shù) |
| CONSTRUCTOR | 構(gòu)造函數(shù) |
| LOCAL_VARIABLE | 局部變量 |
| ANNOTATION_TYPE | 注解類型 |
| PACKAGE | 包 |
| TYPE_PARAMETER | java8,類型變量 |
| TYPE_USE | java8,任何使用類型的語(yǔ)句中 |
@Documented
生成文檔信息的時(shí)候保留注解,對(duì)類作輔助說(shuō)明
@Inhertied
允許子類繼承父類中的注釋
@Repeatable
表示注解可以重復(fù)使用,java8新增
當(dāng)我們需要重復(fù)使用某個(gè)注解時(shí),希望利用相同的注解來(lái)表現(xiàn)所有的形式時(shí),我們可以借助@Repeatable注解。
四、注解處理器
如果沒(méi)有用來(lái)讀取注解的方法和工作,那么注解也就不會(huì)比注釋更有作用了。使用反射機(jī)制的API可以幫助我們快速的構(gòu)造自定義注解處理器。
提取注解:java.lang.reflect.AnnotatedElement接口
isAnnotationPresent判斷該程序元素上是否存在包含指定類型的注解,存在返回true,否則返回false;getAnnotation返回該程序元素上存在的指定類型的注解。如果該類型注解不存在,則返回null;getAnnotations返回該程序元素上存在的所有注解;getAnnotationsByType返回該程序元素上存在的指定類型的所有注解。如果該類型注解不存在,返回長(zhǎng)度為0的數(shù)組。java8;getDeclaredAnnotations返回直接存在于此元素上的所有注解;getDeclaredAnnotation返回直接存在于此元素上的指定類型的注解。如果該類型注解不存在,則返回null。java8;getDeclaredAnnotationsByType返回直接存在于此元素上的指定類型所有注解 。如果該類型注解不存在,返回長(zhǎng)度為0的數(shù)組。java8;
示例:
/** 自定義注解 **/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TestAnnotation {
public String name() default "";
}
/** 注解使用 **/
public class TestClass {
@TestAnnotation(name = "測(cè)試")
public void testMethod() {
System.out.println(" testMethod run ");
}
}
/** 注解處理器 **/
public class TestHandel{
public static void main(String[] arg){
Class clazz = TestClass.class;
Method method = clazz.getMethod("testMethod");
if(method.isAnnotationPresent(TestAnnotation.class)){
TestAnnotation annotation = method.getAnnotation(TestAnnotation.class);
// 打印注解屬性
System.out.println(annotation.name());
// 控制新建的TestClass對(duì)象,執(zhí)行 testMethod 方法
method.invoke(new TestClass());
}
}
}

浙公網(wǎng)安備 33010602011771號(hào)