塔尼亞·辛格java
Java註解使咱們能夠將元數據信息添加到源代碼中,儘管它們不是程序自己的一部分。註解是從JDK 5添加到Java的。註解對其註解的代碼的操做沒有直接影響(即,它不影響程序的執行)。數組
在本教程中,咱們將涵蓋如下主題:註解的用法,如何應用註解,Java中可用的預約義註解類型以及如何建立自定義註解。ide
1)編譯器指令:Java(@Deprecated,@Override&@SuppressWarnings)提供了三個內置註解,可用於向編譯器提供某些指令。例如,@override批註用於指示編譯器已批註的方法將覆蓋該方法。本文的下一部分將討論更多有關這些內置註解的示例。工具
2)編譯時指令:註解能夠向編譯器提供編譯時指令,軟件構建工具能夠將其進一步用於生成代碼,XML文件等。code
3)運行時指令:咱們能夠定義在運行時可用的批註,咱們可使用java反射對其進行訪問,而且能夠在運行時向程序提供指令。在同一篇文章的後面,咱們將藉助示例進行討論。繼承
註解始終以符號開頭,@後跟註解名稱。@
符號向編譯器指示這是一個註解。教程
例如,@Override
在這裏@符號表示這是一個註解,而Override是此註解的名稱。接口
在哪裏可使用註解?
註解能夠應用於類,接口,方法和字段。例如,如下註解將應用於該方法。文檔
@Override void myMethod (){ //作某事}
下一節將說明此註解的確切功能,但要簡要說明一下,它是指示編譯器myMethod()重寫了超類的方法。get
Java具備三個內置註解:
1)@Override:
在子類中重寫方法時,咱們應使用此批註標記該方法。這使代碼易於閱讀並避免了維護問題,例如:在更改父類的方法簽名時,必須在子類(使用此註解的地方)中更改簽名,不然編譯器會拋出編譯錯誤。當您未使用此註解時,很難跟蹤。
例:
public class MyParentClass { public void justaMethod() { System.out.println("Parent class method"); } } public class MyChildClass extends MyParentClass { @Override public void justaMethod() { System.out.println("Child class method"); } }
我相信這個例子是不言自明的。要閱讀有關此註解的更多信息,請參閱本文:@Override 內置註解。
2)@Deprecated
@Deprecated 註解指示已棄用已標記的元素(類,方法或字段),而且不該再使用。每當程序使用已被 @Deprecated 註解標記的方法,類或字段時,編譯器都會生成警告。不推薦使用元素時,還應使用Javadoc @deprecated 標記對其進行記錄,如如下示例所示。使用 @Deprecated 和 @deprecated, 注意大小寫差別。@deprecated用於文檔目的。
例:
/** * @deprecated * reason for why it was deprecated */ @Deprecated public void anyMethodHere(){ // Do something }
如今,只要任何程序使用此方法,編譯器都會生成警告。要閱讀有關此註解的更多信息,請參閱本文:Java – @Deprecated註解。
3)@SuppressWarnings
該註解指示編譯器忽略特定的警告。例如,在下面的代碼中,我正在調用不同意使用的方法(假設方法deprecatedMethod()已用 @Deprecated 註解標記),所以編譯器應生成警告,可是我使用的是 @SuppressWarnings
批註,它將禁止該棄用警告。
@SuppressWarnings("deprecation") void myMethod() { myObject.deprecatedMethod(); }
註解是經過使用 @interface
建立的,後跟註解名稱,如如下示例所示。
註解也能夠具備屬性。它們看起來像方法。例如,在下面的代碼中,咱們有四個屬性。咱們須要爲這些屬性提供相應的getter,setter 方法。
全部註解都擴展了java.lang.annotation.Annotation接口。註解不能包含任何extends
子句, 不像類能夠繼承。
import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target(ElementType.METHOD) @Inherited @Retention(RetentionPolicy.RUNTIME) public @interface MyCustomAnnotation{ int studentAge() default 18; String studentName(); String stuAddress(); String stuStream() default "CSE"; }
注意:使用註解時,能夠跳過建立註解時設置了默認值的全部元素。例如,若是我將上述註解應用於一個類,則能夠這樣進行:
@MyCustomAnnotation( studentName="Chaitanya", stuAddress="Agra, India" ) public class MyClass { ... }
如您所見,咱們沒有給 studentAge 和 stuStream 元素賦予任何值,由於設置這些元素的值是可選的(註解值定義中已經設置了默認值,可是若是您想在使用註解時分配新值,則只需就像咱們對其餘屬性所作的同樣)。可是,在使用註解時,咱們必須提供其餘屬性的值(未設置默認值的屬性)。
注意:咱們也能夠在註解中包含數組屬性。這是咱們如何使用它們:
註解定義:
@interface MyCustomAnnotation { int count(); String[] books(); }
用法:
@MyCustomAnnotation( count=3, books={"C++", "Java"} ) public class MyClass { }
讓咱們回到正題再次:在自定義註解例子中咱們使用這四個註解:@Documented,@Target,@Inherited
和 @Retention
。Java 8之後又引入了 @Repeatable
註解, 有些人把他們稱做元註解,即用於註解的註解,他們共同特色是都被@Target(ElementType.ANNOTATION_TYPE)
所標記,包括@Target
本身。
讓咱們詳細討論它們。
@Documented 註解指示使用此註解的元素應由 JavaDoc 記錄。例如:
java.lang.annotation.Documented @Documented public @interface MyCustomAnnotation { //Annotation body } @MyCustomAnnotation public class MyClass { //Class body }
在爲class生成 javadoc 時 MyClass,@MyCustomAnnotation 將包括註解。
它指定了咱們能夠在哪裏使用註解。例如:在下面的代碼中,咱們將目標類型定義爲 METHOD,這意味着下面的註解只能在方法上使用。
import java.lang.annotation.ElementType; import java.lang.annotation.Target; @Target({ElementType.METHOD}) public @interface MyCustomAnnotation { } public class MyClass { @MyCustomAnnotation public void myMethod() { //Doing something } }
注意:1)若是未定義任何目標類型,則意味着能夠將註解應用於任何元素。
2)除了ElementType.METHOD,註解能夠具備如下可能的Target值。
ElementType.METHOD ElementType.PACKAGE ElementType.PARAMETER ElementType.TYPE ElementType.ANNOTATION_TYPE ElementType.CONSTRUCTOR ElementType.LOCAL_VARIABLE ElementType.FIELD
以上這些放置位置並非徹底的互斥關係,好比 TYPE 實際上能夠放在類、接口、註解類型和枚舉類形前(即包括 ANNOTATION_TYPE 由於他們都是廣義的類)。
@Inherited 註解表示一個類中使用的自定義註解應由其全部子類繼承。例如:
java.lang.annotation.Inherited @Inherited public @interface MyCustomAnnotation { } @MyCustomAnnotation public class MyParentClass { ... } public class MyChildClass extends MyParentClass { ... }
在這裏,該類 MyParentClass 使用的 @MyCustomAnnotation
是帶有 @Inherited
註解的註解。這意味着子類MyChildClass 繼承了@MyCustomAnnotation
。
它指示帶有註解類型的註解將保留多長時間。
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) @interface MyCustomAnnotation { }
在這裏,咱們使用了 RetentionPolicy.RUNTIME。也有兩個其餘選擇。讓咱們看看它們的含義: