Java註解同 classs 和 interface 同樣,註解也屬於一種類型。它是在 Java SE 5.0 版本中開始引入的概念。編程
經過 @interface 關鍵字進行定義。 public @interface TestAnnotation { }
這段代碼就建立了一個名字爲 TestAnnotaion 的註解。安全
你能夠簡單理解爲建立了一張名字爲 TestAnnotation 的標籤。ide
@TestAnnotation public class Test { }
在類上加上@TestAnnotation 就能夠用 TestAnnotation 註解這個類了。函數式編程
@Deprecated、@Override、@SuppressWarnings、@SafeVarargs、@FunctionalInterface函數
@Deprecatedbr/>這個元素是用來標記過期的元素,編譯器在編譯階段遇到這個註解時會發出提醒警告,告訴開發者正在調用一個過期的元素好比過期的方法、過期的類、過期的成員變量。
@Override
提示子類要複寫父類中被 @Override 修飾的方法br/>@SuppressWarnings
阻止警告的意思,把警告取消。br/>@SafeVarargs
參數安全類型註解。它的目的是提醒開發者不要用參數作一些不安全的操做,它的存在會阻止編譯器產生 unchecked 這樣的警告。它是在 Java 1.7 的版本中加入的。br/>@FunctionalInterface
函數式接口註解,這個是 Java 1.8 版本引入的新特性,函數式編程。code
函數式接口 (Functional Interface) 就是一個具備一個方法的普通接口。對象
元註解是能夠註解到註解上的註解,或者說元註解是一種基本註解,可是它可以應用到其它的註解上面。 有 @Retention、@Documented、@Target、@Inherited、@Repeatable 5 種。
@Retention
當 @Retention 應用到一個註解上的時候,它解釋說明了這個註解的的存活時間。
它的取值以下:
RetentionPolicy.SOURCE 註解只在源碼階段保留,在編譯器進行編譯時它將被丟棄忽視。
RetentionPolicy.CLASS 註解只被保留到編譯進行的時候,它並不會被加載到 JVM 中。
RetentionPolicy.RUNTIME 註解能夠保留到程序運行的時候,它會被加載進入到 JVM 中,因此在程序運行時能夠獲取到它們。繼承
@Documented
它的做用是可以將註解中的元素包含到 Javadoc 中去。接口
@Target
@Target 指定了註解運用的地方。當一個註解被 @Target 註解時,這個註解就被限定了運用的場景。
ElementType.ANNOTATION_TYPE 能夠給一個註解進行註解
ElementType.CONSTRUCTOR 能夠給構造方法進行註解
ElementType.FIELD 能夠給屬性進行註解
ElementType.LOCAL_VARIABLE 能夠給局部變量進行註解
ElementType.METHOD 能夠給方法進行註解
ElementType.PACKAGE 能夠給一個包進行註解
ElementType.PARAMETER 能夠給一個方法內的參數進行註解
ElementType.TYPE 能夠給一個類型進行註解,好比類、接口、枚舉開發
@Inherited
Inherited 是繼承的意思,可是它並非說註解自己能夠繼承,而是說若是一個類使用了被Inherited標註的註解,那麼這個類的子類也繼承這個註解。
@Repeatable
Repeatable是可重複的意思,註解容器。@Repeatable 是 Java 1.8 才加進來的,因此算是一個新的特性。
@interface Persons {
Person[] value();
}
@Repeatable(Persons.class)//至關於用來保存該註解內容的容器。
@interface Person{
String role default "";
}
@Person(role="teach")br/>@Person(role="coder")
@Person(role="PM")
public class Man{
}
註解的屬性也叫作成員變量。註解只有成員變量,沒有方法。註解的成員變量在註解的定義中以「無形參的方法」形式來聲明,其方法名定義了該成員變量的名字,其返回值定義了該成員變量的類型。
public @interface TestAnnotation {
int id();
String value();br/>}
使用註解
@TestAnnotation(id=1,value="xxxxx")
public class Test {
}
註解中屬性能夠有默認值,默認值須要用 default 關鍵值指定。
public int id() default -1;
注:
若是一個註解內只有一個屬性時,使用註解時能夠直接接屬性值填寫到括號內。
若是沒有屬性,使用的時候能夠省略括號。
一個註解要在運行時被成功提取,那麼 @Retention(RetentionPolicy.RUNTIME) 是必須的。
註解經過反射獲取。首先能夠經過 Class 對象的 isAnnotationPresent() 方法判斷它是否應用了某個註解
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}
而後經過 getAnnotation() 方法來獲取 Annotation 對象。public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {}
或者是 getAnnotations() 方法。public Annotation[] getAnnotations() {}
前一種方法返回指定類型的註解。
後一種方法返回應用到這個元素上的全部註解。
例子
@Retention(RetentionPolicy.RUNTIME) public @interface TestAnnotation { public int id() default 2; public String value() default "hello"; } @TestAnnotation public class AnnotationTest { public static void main(String[] args) throws ClassNotFoundException { //Class c = Class.forName("com.temp.annotation.AnnotationTest"); boolean hasAnnotation = AnnotationTest.class.isAnnotationPresent(TestAnnotation.class); if (hasAnnotation ) { TestAnnotation testAnnotation = AnnotationTest.class.getAnnotation(TestAnnotation.class); Annotation[] ans = AnnotationTest.class.getAnnotations(); System.out.println(ans[0]); System.out.println("id:"+testAnnotation.id()); System.out.println("value:"+testAnnotation.value()); } } }
運行結果:@com.temp.annotation.TestAnnotation(value=hello, id=2)id:2value:hello