【2016-03-01】Java註解

常常在代碼中看到註解,經常使用的有@Override、@Deprecated、Spring註解。html

@Override代碼以下:java

package java.lang;
import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

Override裏面很乾淨,什麼都沒有,可是外面有。編程

涉及到了兩個元註解:api

@Target :顧名思義,說明@Override能夠用來註解方法oracle

@Retention:定義該註解的生命週期,默認爲RetentionPolicy.CLASS。jvm

類型 使用場景 常見例子
RetentionPolicy.SOURCE 在編譯階段丟棄。這些註解在編譯結束以後就再也不有任何意義,因此它們不會寫入字節碼。 @Override, @SuppressWarnings都屬於這類註解。
RetentionPolicy.CLASS 在類加載的時候丟棄。在字節碼文件的處理中有用。註解默認使用這種方式。
RetentionPolicy.RUNTIME 始終不會丟棄,運行期也保留該註解,所以可使用反射機制讀取該註解的信息。 咱們自定義的註解一般使用這種方式。


查api doc,看到還有另外兩種元註解:ide

@Documented:註解是否將包含在JavaDoc中函數

@Inherited:是否容許子類繼承該註解spa

另外,還發現了一個Annotation接口.net

package java.lang.annotation;

public interface Annotation {
boolean equals(Object obj);
int hashCode();
    Class<? extends Annotation> annotationType();
}

此接口功能以下(雖然有點繞,可是說的仍是挺清楚地):

一、任何註解都繼承了此接口;

二、經過 xxInterface extends Annotation方式繼承的不聲明註解;

三、此接口本身沒有聲明註解。

這個知乎問題知道,註解反編譯以後實際上繼承了Annotation。


言歸正傳,看過了@Override的代碼,會產生2個疑問:

一、@Override的功能(檢查在父類中有一個相同簽名的函數)是誰來完成的?

二、如何自定義一個註解?

咱們先說第二個問題~


1、如何自定義一個Annotation?

簡單如@Retention,發現Retention能夠本身註解本身,這不算犯規。

package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

自定義代碼(引自refer2連接):

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
    int count() default 1;    // 默認是public,default不是必須的,方法必須有返回值;
}

@TestAnnotation(count = 0x7fffffff)
public class TestMain {
    public static void main(String[] args) throws InterruptedException, NoSuchFieldException, IllegalAccessException, IOException {
        TestAnnotation annotation = TestMain.class.getAnnotation(TestAnnotation.class);
        System.out.println(annotation.count());
        System.in.read();
    }
}

refer3裏有個Filed的例子,這個博客被轉的還蠻多的。


2、@Override的功能是誰來完成的?

如今的java IDE都是自動編譯的,編譯的時候就能夠檢查是否正確的Override了父類的方法了~


PS: JVM是如何選擇@Override的方法的?

看了一些博客以後,大概明白了。因爲繼承的存在,變量具備「靜態類型」和「實際類型」,靜態類型在編譯器肯定,實際類型在運行期肯定,執行的時候調用實際類型的Override的方法便可。

Override和Overload的底層實現叫作「分派」(原諒本身第一次見到這個詞)。發現Override是jvm的一個叫「動態分派」的過程完成的,與之相對的靜態分派是重載(Overload)。除此以外還有多分派、單分派這對術語。


3、相關問題

一、Spring中使用註解註冊Bean;

二、XML vs. Annotation


refer:

一、Java中的註解是如何工做的?

二、java註解是怎麼實現的?

三、java 註解的基本原理和編程實現

相關文章
相關標籤/搜索