Java註解(annotation)基本使用

一、基本概念

在開發Java程序,尤其是Java EE應用的時候,總是免不了與各種配置文件打交道。以Java EE中典型的S(pring)S(truts)H(ibernate)架構來說,Spring、Struts和Hibernate這三個框架都有自己的XML格式的配置文件。這些配置文件需要與Java源代碼保存同步,否則的話就可能出現錯誤。而且這些錯誤有可能到了運行時刻才被發現。把同一份信息保存在兩個地方,總是個壞的主意。理想的情況是在一個地方維護這些信息就好了。其它部分所需的信息則通過自動的方式來生成。JDK 5中引入了源代碼中的註解(annotation)這一機制。註解使得Java源代碼中不但可以包含功能性的實現代碼,還可以添加元數據。註解的功能類似於代碼中的註釋,所不同的是註解不是提供代碼功能的說明,而是實現程序功能的重要組成部分。Java註解已經在很多框架中得到了廣泛的使用,用來簡化程序中的配置。

 

二、常用的Java內置註解

Java中常用的內置註解是以下三種:

  • @Override:表示當前方法將重寫父類的相同簽名的方法;
  • @Deprecated:表示該類或者方法是不建議被使用的,當用戶使用時編譯器會給出警告;
  • @SuppressWarnings:表示暫時關閉指定的編譯器警告。

三、自定義註解

自定義註解的定義與接口定義相似,當註解定義後也會被編譯爲class文件。

定義自己的註解需要用到Java提供的元註解去修飾自定義註解:

@Target:表示該自定義註解所適用的程序元素的種類(方法,局部變量,類等),省略則表示該註解能應用於所有程序元素,其值爲java.lang.annotation.ElementType枚舉類型:

  • TYPE:類、接口或枚舉類型的定義;
  • FIELD:成員變量(包括enum實例)的聲明;
  • METHOD:方法聲明;
  • PARAMETER:方法參數聲明;
  • CONSTRUCTOR:構造函數聲明;
  • LOCAL_VARIABLE:局部變量聲明;
  • ANNOTATION_TYPE:註解的定義;
  • PACKAGE:包聲明。

@Retention:表示要在什麼級別保存自定義註解信息,即該自定義註解需要保存多久。其值爲java.lang.annotation.RetentionPolicy枚舉類型:

  • SOURCE:自定義的註解信息只會保存在源代碼,當編譯時會被編譯器忽略;
  • CLASS:自定義的註解信息會被編譯器保存進class文件,但會在運行時被VM忽略(默認行爲);
  • RUNTIME:在CLASS的基礎上,VM同時會在運行時保存註解信息,因此可以通過反射讀取。

@Documented:表示自定義註解需要包含在javadoc中;

 

@Inherited:表示允許子類繼承父類的自定義註解。

 

示例一:

package annotation;

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


/**
 * 自定義註解@MyAnnotation,能用於方法定義,並能在運行時獲取。
 * 註解中有一個屬性value。
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    public String value();
}

 

package annotation;

import java.lang.reflect.Method;

/**
 * 使用自定義的註解
 */
public class AnnotationTest {
    //當註解中只有唯一的名叫value的屬性時,可以只寫屬性值傳參
    @MyAnnotation("test")
    public static void main(String[] args) {
        //使用反射獲取main方法的Method對象
        Method mainMethod = AnnotationTest.class.getMethods()[0];
        //在Method對象上獲取@MyAnnotation註解
        MyAnnotation myAnnotation = mainMethod.getAnnotation(MyAnnotation.class);
        //獲取註解的value屬性
        System.out.println("@MyAnnotation: " + myAnnotation.value());
    }
}

 

 輸出:

@MyAnnotation: test

 

 

示例二:

package annotation;

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

/**
 * 自定義註解@MyAnnotation,能用於方法定義,並能在運行時獲取。
 * 註解中有兩個屬性id和message,message使用default提供默認值。
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    public int id();

    public String message() default "None";
}

 

package annotation;

import java.lang.reflect.Method;

public class AnnotationTest {
    //當value不是註解中的唯一屬性時,需要以
    //屬性名=屬性值的形式賦值
    @MyAnnotation(id = 1)
    public static void main(String[] args) {
        Method mainMethod = AnnotationTest.class.getMethods()[0];
        MyAnnotation testAnnotation = mainMethod.getAnnotation(MyAnnotation.class);

        System.out.println("id: " + testAnnotation.id());
        //message會輸出默認值None
        System.out.println("message: " + testAnnotation.message());
    }
}

 

 輸出:

id: 1
message: None

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章