java中的註解總結

1. 什麼是註解

註解是java5引入的特性,在代碼中插入一種註釋化的信息,用於對代碼進行說明,能夠對包、類、接口、字段、方法參數、局部變量等進行註解。註解也叫元數據(meta data)。這些註解信息能夠在編譯期使用預編譯工具進行處理(pre-compiler tools),也能夠在運行期使用 Java 反射機制進行處理。
它主要的做用有如下四方面:java

  • 生成文檔,經過代碼裏標識的元數據生成javadoc文檔。
  • 編譯檢查,經過代碼裏標識的元數據讓編譯器在編譯期間進行檢查驗證。
  • 編譯時動態處理,編譯時經過代碼裏標識的元數據動態處理,例如動態生成代碼。
  • 運行時動態處理,運行時經過代碼裏標識的元數據動態處理,例如使用反射注入實例。

通常註解能夠分爲三類:app

  • 一類是Java自帶的標準註解,包括@Override@Deprecated@SuppressWarnings,分別用於標明重寫某個方法、標明某個類或方法過期、標明要忽略的警告,用這些註解標明後編譯器就會進行檢查。
  • 一類爲元註解,元註解是用於定義註解的註解,包括@Retention@Target@Inherited@Documented@Retention用於標明註解被保留的階段,@Target用於標明註解使用的範圍,@Inherited用於標明註解可繼承,@Documented用於標明是否生成javadoc文檔。
  • 一類爲自定義註解,能夠根據本身的需求定義註解,並可用元註解對自定義註解進行註解。

2. 註解的原理

爲何在類、方法上加一個註解,就能夠經過getAnnotation()獲取到申明的註解的值?
好比:ide

@Test("test")
public class AnnotationTest {
    public void test(){
    }
}

對於註解test就能夠在運行時經過AnnotationTest.class.getAnnotation(Test.class)獲取註解聲明的值。工具

  1. 註解信息保存在哪兒?
  2. 註解信息如何獲取?

在AnnotationTest類被編譯後,在對應的AnnotationTest.class文件中會包含一個RuntimeVisibleAnnotations屬性,因爲這個註解是做用在類上,因此此屬性被添加到類的屬性集上。即Test註解的鍵值對value=test會被記錄起來。而當JVM加載AnnotationTest.class文件字節碼時,就會將RuntimeVisibleAnnotations屬性值保存到AnnotationTest的Class對象中,因而就能夠經過AnnotationTest.class.getAnnotation(Test.class)獲取到Test註解對象,進而再經過Test註解對象獲取到Test裏面的屬性值。
這裏可能會有疑問,Test註解對象是什麼?其實註解被編譯後的本質就是一個繼承Annotation接口的接口,因此@Test其實就是「public interface Test extends Annotation」,當咱們經過AnnotationTest.class.getAnnotation(Test.class)調用時,JDK會經過動態代理生成一個實現了Test接口的對象,並把將RuntimeVisibleAnnotations屬性值設置進此對象中,此對象即爲Test註解對象,經過它的value()方法就能夠獲取到註解值。.net

3. 四種類型註解

註解能夠經過做用的類型可分爲:類註解、方法註解、參數註解、變量註解。代理

類註解
訪問類註解的例子:code

Class aClass = TheClass.class;
Annotation[] annotations = aClass.getAnnotations();

for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotation) annotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
}

此方法獲取到的是該類的全部註解,也可指定某一個類:對象

Class aClass = TheClass.class;
Annotation annotation = aClass.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotation) annotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}

Spring中的@Service``@Controller便是如此。blog

方法註解繼承

public class TheClass {
  @MyAnnotation(name="someName",  value = "Hello World")
  public void doSomething(){}
}

獲取方法對象的指定註解:

Method method = ... // 獲取方法對象
Annotation annotation = method.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotation) annotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}

SpringMVC中的@RequestMapping便是如此。

參數註解
方法的參數也能夠添加註解:

public class TheClass {
  public static void doSomethingElse(
        @MyAnnotation(name="aName", value="aValue") String parameter){
  }
}

訪問註解:

Method method = ... //獲取方法對象
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
Class[] parameterTypes = method.getParameterTypes();

int i=0;
for(Annotation[] annotations : parameterAnnotations){
  Class parameterType = parameterTypes[i++];

  for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotation) annotation;
        System.out.println("param: " + parameterType.getName());
        System.out.println("name : " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
  }
}

Mybatis中的@Param便是如此

變量註解
使用註解:

public class TheClass {

  @MyAnnotation(name="someName",  value = "Hello World")
  public String myField = null;
}

獲取註解:

Field field = ...//獲取方法對象</pre>
<pre>
Annotation annotation = field.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
 MyAnnotation myAnnotation = (MyAnnotation) annotation;
 System.out.println("name: " + myAnnotation.name());
 System.out.println("value: " + myAnnotation.value());
}

Spring中的@Inject``@Resource便是如此。

參考資料:
註解機制及其原理
Java Reflection(八):註解

相關文章
相關標籤/搜索