註解的認識和理解
在學習框架的過程中我們經常會看到在類頂端有@+相應的描述,在定義了一個接口之後,在寫實現類實現接口方法的時候我們會在方法的頂端看到@Override這樣的字樣,所有的這些都是註解相關的內容,本篇博客將和大家詳細學習和了解下有關注解的內容。
常見的註解類型
在整個Java中我們常見的註解主要可以歸納爲以下三種:
- JDK註解
- 第三方註解
- 自定義註解
JDK註解
JDK註解是我們日常開發中最爲常見的註解,主要有:@Override,@Deprecated,@SuppressWarnings。他們各自的功能:
1. @Override代表的是子類對父類方法進行了覆寫,如果父類沒有定義該方法,子類方法有該參數就會出現編譯異常。
2. 使用了@Deprecated註解,意味着當前的方法或者類已經過時了,被棄用了,在引用的時候會報警告。
3. @SuppressWarnings該註解表示的是忽略某個警告通過在()中寫入字符串,來確定忽略的警告類型
第三方註解
第三方註解一般出現在我們使用的框架上例如在使用Spring的時候我們會用到@AutoWired、@Service以及@Repository,MyBatis會用到@InsertProvider,@UpdateProvider以及@Options等。
自定義註解
自定義註解顧名思義就是我們爲達到某種編程目的自定義的註解,在講解自定義註解的時候我們首先需要了解的是元註解的用法:元註解的類型主要有@Target,@Retention,@Inherited,@Documented,是自定義註解用到的註解。這裏分別說下各個元註解的意義和用法:
1. @Target該註解內部定義的是註解使用的對象,內部可以傳入的參數主要有ElementType.CONSTRUCTOR(構造方法聲明),FIELD(字段聲明),LOCALVARIABLE(局部變量聲明),METHOD(方法聲明),PACKAGE(包聲明),PARAMETER(參數聲明),TYPE(類接口)。
2. @Retention註解則用來確定該註解的的生命週期內部傳的參數主要有三種:RetentionPolicy.SOURCE/CLASS/RUNTIME,其中SOURCE 代表的是該註解只在源碼中顯示在編譯是丟棄,CLASS則是編譯時記錄到CLASS,運行時忽略,RUNTIME代表的是運行時有效可以通過反射讀取。
3. @Inherited代表的是註解可繼承,該註解不需要傳參數,如果該註解最終用在了父類上,在獲取該註解的時候我們可以通過向他的子類獲取相應的屬性值,JVM會自下向上去不斷地尋找直到找到註解引用的類爲止。
4. @Document則表示源代碼在生成javadoc的過程中該註解是否也作爲內容顯示在代碼的上方,有該註解則顯示沒有則不顯示。
註解獲取的方法
在談註解獲取的時候必須要說的就是反射的知識,這裏我主要說兩種獲取的註解的方法以及詳細流程:
1.類加載模式:
- 調用Class.forName()拿到類對象
- 根據註解適用位置獲取相應的屬性(ElementType的類型)
- 調用isAnnotationPresent方法判斷是否使用註解
- 調用getAnnotation拿到註解
- 回調註解中的方法名拿到對應的數值
代碼如下:
public static void main(String[] args){
try{
Class stuClass=Class.forName("com.hyt.service.IStuSelectImpl");
boolean isAnnotated=stuClass.isAnnotationPresent(ClassInfo.class);
if(isAnnotated){
ClassInfo classInfo=stuClass.getAnnotation(ClassInfo.class);
System.out.println("註解對應的信息是:"+classInfo.value());
}else{
System.out.println("該註解不存在");
}
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
2.帶有泛型的類對象:
- 通過Class stuClass=MethodInfo.class;獲取類對象
- 判斷是否使用了定義好的註解
- 若使用了註解,獲得該註解對應的實例
- 通過實例調用相關方法獲取屬性值
代碼如下:
public static void main(String[] args){
Class<MethodInfo> methClass=MethodInfo.class;
boolean isAnnotated=methClass.isAnnotationPresent(MethodInfo.class);
if(isAnnotated){
MethodInfo methInfo=methClass.getAnnotation(MethodInfo.class);
System.out.println("方法名:"methInfo.name()+" 方法描述:"+methInfo.comments());
}else{
System.out.println("註解不存在");
}
}
總結:
學習註解的關鍵一方面要了解四種元註解各自的用法和代表的意思,另外一方面則是要知道獲取註解的流程。當然學以致用,我們學習註解的主要目的還是爲了在以後的編碼過程中能夠用的上這種注入數據的特殊方式,同時也有助於我們理解常用框架的編程思想和底層邏輯。