Java註解-元數據、註解分類、內置註解和自定義註解

今天我們來看看Java編程裏的註解。

Java註解-元數據、註解分類、內置註解和自定義註解

Java註解

Java註解有以下幾個知識點:

  • 元數據

  • 註解的分類

  • 內置註解

  • 自定義註解

  • 註解處理器

  • Servlet3.0

本文先介紹前面4個知識點:元數據、註解的分類、內置註解、自定義註解。

 一、註解簡介

註解是Java 1.5引入的,目前已被廣泛應用於各種Java框架,如Hibernate,Jersey,

Spring。註解相當於是一種嵌入在程序中的元數據,可以使用註解解析工具或編譯器對

其進行解析,也可以指定註解在編譯期或運行期有效。

在註解誕生之前,程序的元數據存在的形式僅限於java註釋或javadoc,但註解可以提

供更多功能,它不僅包含元數據,還能作用於運行期,註解解析器能夠使用註解決定處

理流程。

Annotation(註解)就是Java提供了一種元程序中的元素關聯任何信息和任何元數據

(metadata)的途徑和方法。Annotation是一個接口,程序可以通過反射來獲取指定

程序元素的Annotation對象,然後通過Annotation對象來獲取註解裏面的元數據。

註解API非常強大,被廣泛應用於各種Java框架,如Spring,Hibernate,JUnit。

二、 元數據metadata

元數據從metadata一詞譯來,就是“關於數據的數據”的意思,即描述數據的結構信息。元數據的功能作用有很多,比如:你可能用過Javadoc的註釋自動生成文檔。這就是元數據功能的一種。總的來說,元數據可以用來創建文檔,跟蹤代碼的依賴性,執行編譯時格式檢查,代替已有的配置文件。

在Java中元數據以標籤的形式存在於Java代碼中,元數據標籤的存在並不影響程序代碼的編譯和執行,被用來生成其它的文件或只在運行時知道被運行代碼的描述信息。

其作用如下:

①生成文檔:這是最常見的,也是java 最早提供的註解。常用的有@param @return 等;

② 跟蹤代碼依賴性,實現替代配置文件功能。常見的是spring 2.5 開始的基於註解配置。作用就是減少配置。現在的框架基本都使用了這種配置來減少配置文件的數量。;

③在編譯時進行格式檢查。如@override 放在方法前,如果你這個方法並不是覆蓋了超類方法,則編譯時就能檢查出。

三、 註解的分類

根據註解參數的個數:

1)、標記註解:一個沒有成員定義的Annotation類型被稱爲標記註解。

2)、單值註解:只有一個值

3)、完整註解:擁有多個值

根據註解使用方法和用途:

1)、JDK內置系統註解

2)、元註解

3)、自定義註解

四、 內置註解

JavaSE中內置三個標準註解,定義在java.lang中:

@Override

限定重寫父類方法,若想要重寫父類的一個方法時,需要使用該註解告知編譯器我們正在重寫一個方法。如此一來,當父類的方法被刪除或修改了,編譯器會提示錯誤信息;或者該方法不是重寫也會提示錯誤。

public interface Car {
	void run();
}
class QQ implements Car{
	@Override
	public void run() {}
}
class Bmw implements Car{
	@Override
	void run() {}
}

QQ 類編譯不會有任何問題,Bmw類在編譯的時候會提示相應的錯誤。父類中省略了public abstract修飾符。@Override註解只能用於方法,不能用於其他程序元素。

@Deprecated

標記已過時,當我們想要讓編譯器知道一個方法已經被棄用(deprecate)時,應該使用這個註解。Java推薦在javadoc中提供信息,告知用戶爲什麼這個方法被棄用了,以及替代方法是什麼;

/**
 * Deprecated -->該方法過時(有更好的解決方案)
 * @author Administrator
 */
public class TestDeprecated {
	@Deprecated
	public int test(){
		System.out.println("TestDeprecated.test()");
		return 0;
	}
	public void test(int a){
		System.out.println("TestDeprecated.test(int)");
	}
}

3. @SuppressWarnings

抑制編譯器警告,該註解僅僅告知編譯器,忽略它們產生了特殊警告。如:在java泛型中使用原始類型。其保持性策略(retention policy)是SOURCE,在編譯器中將被丟棄。

/**
 * SuppressWarnings 壓制警告
 * @author Administrator
 */
public class TestSuppressWarnings {
	public static void main(String[] args) {
		@SuppressWarnings("unused")
		List<String> list =new ArrayList<String>();
	}
	@SuppressWarnings("rawtypes") //沒有定義範型
	public static List test(){
		return new ArrayList();
	}
}

五、 自定義註解

1、簡單入門

@interface:用來聲明一個註解。註解類裏的每一個方法實際上是聲明瞭一個配置參數。方法的名稱就是參數的名稱,返回值類型就是參數的類型。可以通過default來聲明參數的默認值。

@interface Simple{
//這裏定義了一個空的註解,它能幹什麼呢?我也不知道,但他能用。後面有補充
}

2、元註解

元註解的作用就是負責註解其他註解。Java5.0定義了4個標準的meta-annotation類型,它們被用來提供對其它 annotation類型作說明。Java5.0定義的元註解有四個,

這些類型和它們所支持的類在java.lang.annotation包中可以找到。

@Target

用於描述註解的使用範圍(即:被描述的註解可以用在什麼地方)。表示支持註解的程序元素的種類,一些可能的值有TYPE, METHOD, CONSTRUCTOR, FIELD等等。如果Target元註解不存在,那麼該註解就可以使用在任何程序元素之上。

取值(ElementType)有:

 1.CONSTRUCTOR:用於描述構造器

 2.FIELD:用於描述域

 3.LOCAL_VARIABLE:用於描述局部變量

 4.METHOD:用於描述方法

 5.PACKAGE:用於描述包

 6.PARAMETER:用於描述參數

 7.TYPE:用於描述類、接口(包括註解類型) 或enum聲明

此時在空註解中加入@Target元註解如:

//此註解只能用在方法上
@Target(ElementType.METHOD) 
@interface TestMethod {}

@Retention

表示需要在什麼級別保存該註釋信息,用於描述註解的生命週期(即:被描述的注在什麼範圍內有效)表示註解類型保留時間的長短。

取值(RetentionPoicy)有:

1.SOURCE:在源文件中有效(即源文件保留)

2.CLASS:在class文件中有效(即class保留)

3.RUNTIME:在運行時有效(即運行時保留)

此時在上述註解中加入@Retention元註解如:

// 此註解可以用於註解類、接口(包括註解類型) 或enum聲明
@Target(ElementType.TYPE) 
//該註解運行時有效。註解處理器可以通過反射,獲取到該註解的屬性值,從而去做一些運行時的邏輯處理
@Retention(RetentionPolicy.RUNTIME)
@interface TestRn{
}

@Documented

表示使用該註解的元素應被javadoc或類似工具文檔化,它應用於類型聲明,類型聲明的註解會影響客戶端對註解元素的使用。如果一個類型聲明添加了Documented註解,那麼它的註解會成爲被註解元素的公共API的一部分,@Documented是一個標記註解。

//可以被例如javadoc此類的工具文檔化
@Documented
@interface TestDoc{	
}

@Inherited

表示一個註解類型會被自動繼承,如果用戶在類聲明的時候查詢註解類型,同時類聲明中也沒有這個類型的註解,那麼註解類型會自動查詢該類的父類,這個過程將會不停地重複,直到該類型的註解被找到爲止,或是到達類結構的頂層(Object)。

//被子類繼承的註解
@Inherited
@interface TestInheri{}

3、深入自定義註解

使用@interface自定義註解時,自動繼承了java.lang.annotation.Annotation接口,由編譯程序自動完成其他細節。在定義註解時,不能繼承其他的註解或接口。

⑴定義註解格式:

@interface用來聲明一個註解,其中的每一個方法實際上是聲明瞭一個配置參數。方法的名稱就是參數的名稱,返回值類型就是參數的類型(返回值類型只能是基本類型、Class、String、enum)。可以通過default來聲明參數的默認值。

public @interface 註解名{定義體s}

⑵註解參數(即方法)

註解裏面的每一個方法實際上就是聲明瞭一個配置參數,其規則如下:

①修飾符

只能用public或默認(default)這兩個訪問權修飾 ,默認爲default

②類型

註解參數只支持以下數據類型:

基本數據類型(int,float,boolean,byte,double,char,long,short);

String類型;

Class類型;

enum類型;

Annotation類型;

以上所有類型的數組

③命名

對取名沒有要求,如果只有一個參數成員,最好把參數名稱設爲"value",後加小括號。

④參數

註解中的方法不能存在參數

⑤默認值

可以包含默認值,使用default來聲明默認值。

⑶實例如下

/*
 * 碼農定義註解
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface Programmer{
	String value() default "馬雲";
}
/**
 * 碼農類型註解
 * @author peida
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface ProgrammerType {
 /**
 * 類型枚舉 程序猿 射雞師
 */
 public enum CoderType{MONKEYS,LION,CHOOK};
 /**
 * 顏色屬性
 */
 CoderType type() default CoderType.MONKEYS;
}
/**
 * 碼農製造廠
 * @author Administrator
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface ProgrammerProductor {
 /**
 * 廠家編號
 * @return
 */
 public int id() default -1;
 /**
 * 廠家名稱
 * @return
 */
 public String name() default "shsxt"; 
 /**
 * 廠家地址
 * @return
 */
 public String address() default "上海";
}
/**
 * 註解使用
*/
class Coder{
		@Programmer("老裴")
	 private String coderName;
		@ProgrammerType(type=CoderType.MONKEYS)
	 private String coderType;
		@ProgrammerProductor(id=1,name="程序猿樂園",address="榮樂東路")
	 private String coderProductor;
		public String getCoderName() {
			return coderName;
		}
		public void setCoderName(String coderName) {
			this.coderName = coderName;
		}
		public String getCoderType() {
			return coderType;
		}
		public void setCoderType(String coderType) {
			this.coderType = coderType;
		}
		public String getCoderProductor() {
			return coderProductor;
		}
		public void setCoderProductor(String coderProductor) {
			this.coderProductor = coderProductor;
		}	
}
樂字節原創,轉載請註明出處


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