Java註解教程和示例

Java註解教程和示例

塔尼亞·辛格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內置註解

Java具備三個內置註解:

  • @Override
  • @Deprecated
  • @SuppressWarnings

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

@Documented 註解指示使用此註解的元素應由 JavaDoc 記錄。例如:

java.lang.annotation.Documented
@Documented
public @interface MyCustomAnnotation {
  //Annotation body
}
@MyCustomAnnotation
public class MyClass { 
     //Class body
}

在爲class生成 javadoc 時 MyClass,@MyCustomAnnotation 將包括註解。

@Target

它指定了咱們能夠在哪裏使用註解。例如:在下面的代碼中,咱們將目標類型定義爲 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 繼承

@Inherited 註解表示一個類中使用的自定義註解應由其全部子類繼承。例如:

java.lang.annotation.Inherited

@Inherited
public @interface MyCustomAnnotation {

}
@MyCustomAnnotation
public class MyParentClass { 
  ... 
}
public class MyChildClass extends MyParentClass { 
   ... 
}

在這裏,該類 MyParentClass 使用的 @MyCustomAnnotation 是帶有 @Inherited 註解的註解。這意味着子類MyChildClass 繼承了@MyCustomAnnotation

@Retention 保留

它指示帶有註解類型的註解將保留多長時間。

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@interface MyCustomAnnotation {
    
}

在這裏,咱們使用了 RetentionPolicy.RUNTIME。也有兩個其餘選擇。讓咱們看看它們的含義:

  • RetentionPolicy.RUNTIME 註解應該在運行時可用,以便經過Java反射進行檢查。
  • RetentionPolicy.CLASS:註解將位於.class文件中,但在運行時將不可用。
  • RetentionPolicy.SOURCE 註解將在程序的源代碼中提供,而不是在.class文件中,也不在運行時可用。
相關文章
相關標籤/搜索