注解不斷是Java的一個(gè)十分重要的局部,它從J2SE5.0開端就曾經(jīng)存在了。在我們的應(yīng)用程序代碼中,經(jīng)??吹紷Override和@Deprecated這樣的注解。在本文中,我將討論注解到底是什么,為什么引入注解,它們是如何工作的,如何編寫自定義注解(有示例代碼),注解的有效場景是什么,最后是注解和ADF。這將是一個(gè)很長的帖子,所以來一點(diǎn)咖啡,準(zhǔn)備好進(jìn)入注解的世界。
1.注解是什么?
用一個(gè)詞來能夠解釋:注解即是元數(shù)據(jù)。元數(shù)據(jù)是關(guān)于數(shù)據(jù)的數(shù)據(jù)。所以注解是代碼的元數(shù)據(jù)。舉個(gè)例子,查看下面的代碼。
@Override
publicStringtoString(){
return”ThisisStringRepresentationofcurrentobject.”;
}
我在以上代碼中重寫toString()辦法時(shí)運(yùn)用了@Override注解。即便我不運(yùn)用@Override,代碼依然可以正常工作,沒有任何問題。那么,這個(gè)注解的優(yōu)點(diǎn)是什么?又代表了什么?@Override通知編譯器,此辦法是一個(gè)重寫的辦法(有關(guān)該辦法的元數(shù)據(jù)),假如父類中不存在此類辦法,則引發(fā)編譯器錯(cuò)誤(超類中沒有被掩蓋其的辦法)。如今,假如我犯了一個(gè)排版錯(cuò)誤,并運(yùn)用辦法名為toStrring(){doubler}假如我沒有運(yùn)用@Override,我的代碼會(huì)勝利地編譯和執(zhí)行,但是結(jié)果將會(huì)與預(yù)期不同。如今,我們了解了注解是什么,閱讀正式的定義是很有用途的。
注解是一種特殊的Java結(jié)構(gòu),用于修飾類、辦法、字段、參數(shù)、變量、結(jié)構(gòu)函數(shù)或包。這是JSR-175選擇的提供元數(shù)據(jù)的工具。
2.為什么引入注解?
在注解呈現(xiàn)之前(以至之后),XML被普遍地用于元數(shù)據(jù),但是,一局部特定的應(yīng)用程序開發(fā)人員和架構(gòu)師以為XML維護(hù)變得費(fèi)事了。他們希望可以經(jīng)過某種方式與代碼嚴(yán)密耦合,來替代XML,由于XML與代碼十分松懈地耦合(在某些狀況下,簡直是獨(dú)立的)。假如你在谷歌上搜索“XMLvsannotations”,你會(huì)發(fā)現(xiàn)很多有趣的爭論。有趣的一點(diǎn)是,XML配置是為了將配置從代碼中別離出來而引入的。最后兩種說法可能會(huì)在你的腦海中產(chǎn)生一些疑問,即這兩種說法都在發(fā)明一個(gè)循環(huán),但兩者各有優(yōu)缺陷。讓我們?cè)囍靡粋€(gè)例子來了解。
假定您希望設(shè)置一些應(yīng)用程序范圍的常量/參數(shù)。在這個(gè)場景中,XML將是一個(gè)更好的選擇,由于這與任何特定的代碼段無關(guān)。假如您希望將某些辦法公開為效勞,那么注解將是一個(gè)更好的選擇,由于它需求與該辦法嚴(yán)密耦合,并且該辦法的開發(fā)人員必需曉得這一點(diǎn)。
另一個(gè)重要要素是注解定義了在代碼中定義元數(shù)據(jù)的規(guī)范辦法。在注解之前,人們還運(yùn)用本人的辦法來定義元數(shù)據(jù)。一些例子是運(yùn)用標(biāo)志接口、注解、暫時(shí)關(guān)鍵字等。每個(gè)開發(fā)人員都需求依據(jù)本人的方式來決議元數(shù)據(jù),但是注解是規(guī)范化的東西。
往常,大多數(shù)框架都將XML和注解分離起來,充沛應(yīng)用兩者的優(yōu)點(diǎn)。
3.注解如何工作以及如何編寫自定義注解
在開端解釋之前,我倡議您下載這個(gè)注釋(AnnotationsSample.zip)的示例代碼,并在您常用的IDE中堅(jiān)持翻開,由于它將協(xié)助您更好天文解下面的解釋。
編寫注解十分簡單。您能夠?qū)⒆⒔舛x與接口定義停止比擬。讓我們看兩個(gè)例子—一個(gè)是規(guī)范@Override第二個(gè)注解是自定義注解。@Todo:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public@interfaceOverride{
}
似乎有些可疑之處@Override它沒有做任何事情—它只是檢查能否在父類中定義了一個(gè)辦法。別詫異,我不是在開玩笑。重寫注解的定義只要那么多代碼。這是需求了解的最重要的局部,我重申一遍:注解只是元數(shù)據(jù),不包含任何業(yè)務(wù)邏輯。很難了解但卻是真的。假如注解不包含邏輯,那么一定有人在做一些事情,并且有人是這個(gè)注解元數(shù)據(jù)的消費(fèi)者。注解只提供有關(guān)定義的屬性(類/辦法/包/字段)的信息。消費(fèi)者是一段代碼,它讀取這些信息,然后執(zhí)行必要的邏輯。
當(dāng)我們議論規(guī)范注解時(shí),比方@Override,JVM是運(yùn)用者,它是在字節(jié)碼級(jí)別工作的。這是應(yīng)用程序開發(fā)人員無法控制、也不能用于自定義注解的東西。因而,我們需求為我們本人的注解寫一些消費(fèi)實(shí)例。
讓我們逐一了解用于編寫注解的關(guān)鍵術(shù)語。在上面的例子中,您將看到注解如何被應(yīng)用。
J2SE5.0在java.lang.annotation包中提供了四個(gè)注解,它們僅在編寫注解時(shí)運(yùn)用:
@Documented–能否將注解放在Javadocs中
@Retention–注解什么時(shí)分被保存
@Target?–注解能夠運(yùn)用的中央
@Inherited–子類能否能夠繼承注解。
@Documented-一個(gè)簡單的標(biāo)志注解,它標(biāo)識(shí)了能否將注解添加到Javadoc中。
@Retention-定義應(yīng)保存注解的時(shí)間。
RetentionPolicy.SOURCE在編譯期間丟棄。這些注解在編譯完成后沒有任何意義,因而它們不會(huì)被寫入字節(jié)碼。例子:@Override,@SuppressWarnings
RetentionPolicy.CLASS–在類加載期間丟棄。應(yīng)用在停止字節(jié)碼級(jí)別的編譯期間。有些令人詫異的是,這是默許的。
RetentionPolicy.RUNTIME–不會(huì)丟棄。該注解能夠在運(yùn)轉(zhuǎn)時(shí)停止反射。這是我們通常用于自定義注解的內(nèi)容。
@Target-注解能夠運(yùn)用的中央。假如不指定這一屬性,注解能夠應(yīng)用在任何中央。以下是該注解的有效值。這里的一個(gè)要點(diǎn),它只要包含的方式,這意味著假如您想要對(duì)7個(gè)屬性停止注解,并且只想掃除一個(gè)屬性,這時(shí)需求在定義目的時(shí)包含一切7個(gè)屬性。
ElementType.TYPE(類,接口,枚舉)
ElementType.FIELD(實(shí)例變量)
ElementType.METHOD
ElementType.PARAMETER
ElementType.CONSTRUCTOR
ElementType.LOCAL_VARIABLE
ElementType.ANNOTATION_TYPE(用于其他注解)
ElementType.PACKAGE(記住package-info.java)
@Inherited-控制注解能否應(yīng)該影響子類。
如今,注解定義中包含了什么?注解只支持根本類型、字符串和枚舉。注解的一切屬性都定義為辦法,并且還能夠提供默許值。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interfaceTodo{
publicenumPriority{LOW,MEDIUM,HIGH}
publicenumStatus{STARTED,NOT_STARTED}
Stringauthor()default”Yash”;
Prioritypriority()defaultPriority.LOW;
Statusstatus()defaultStatus.NOT_STARTED;
}
以下是如何運(yùn)用上述注解的示例:
@Todo(priority=Todo.Priority.MEDIUM,author=”Yashwant”,status=Todo.Status.STARTED)
publicvoidincompleteMethod1(){
//Somebusinesslogiciswritten
//Butit’snotcompleteyet
}
假如注解中只要一個(gè)屬性,則應(yīng)該將其命名為“value”,并且能夠在運(yùn)用時(shí)不運(yùn)用屬性稱號(hào)。
@interfaceAuthor{
Stringvalue();
}
@Author(“Yashwant”)
publicvoidsomeMethod(){
}
目前為止一切順利。我們?cè)?jīng)定義了自定義注解,并將其應(yīng)用于一些業(yè)務(wù)邏輯辦法。如今,是時(shí)分寫一個(gè)消費(fèi)的實(shí)例了。為了完成這個(gè)目的,我們需求運(yùn)用到反射。假如您熟習(xí)反射代碼,那么您就曉得反射提供了類、辦法和字段對(duì)象。一切這些對(duì)象都有一個(gè)getAnnotation()辦法,該辦法返回注解對(duì)象。我們需求將此對(duì)象轉(zhuǎn)換為自定義注解(在運(yùn)用instanceOf()檢查之后),然后,我們能夠調(diào)用自定義注解中定義的辦法。讓我們看一下示例代碼,它運(yùn)用了上面的注解:
ClassbusinessLogicClass=BusinessLogic.class;
for(Methodmethod:businessLogicClass.getMethods()){
TodotodoAnnotation=(Todo)method.getAnnotation(Todo.class);
if(todoAnnotation!=null){
System.out.println(“MethodName:”+method.getName());
System.out.println(“Author:”+todoAnnotation.author());
System.out.println(“Priority:”+todoAnnotation.priority());
System.out.println(“Status:”+todoAnnotation.status());
}
}
4.注解用例
注解十分的強(qiáng)大,Spring和Hibernate等框架十分普遍地運(yùn)用注解停止日志記載和考證。注解能夠在運(yùn)用標(biāo)志接口的中央運(yùn)用。標(biāo)志接口用于整個(gè)類,但您能夠定義能夠用于單個(gè)辦法的注解,例如,某個(gè)辦法能否公開為效勞辦法。
在servlet3.0標(biāo)準(zhǔn)中,引入了許多注解,特別是與servlet平安有關(guān)的注解。我們先來看看幾個(gè):
HandlesTypes-此注解用于聲明傳送給ServletContainerInitializer的應(yīng)用程序類數(shù)組。
HttpConstraint-此注解表示應(yīng)用于一切具有HTTP協(xié)議辦法類型的懇求的平安約束,在ServletSecurity上沒有相應(yīng)的HttpMethodConstraint注解時(shí)。
HttpMethodConstraint-特定的平安約束能夠應(yīng)用于不同類型的懇求,在ServletSecurity上注解。
MultipartConfig-此注解用于指示聲明它的servlet將運(yùn)用multiPart/form-DataMIME類型發(fā)出懇求。
ServletSecurity-在servlet完成類上聲明此注解,對(duì)HTTP協(xié)議懇求執(zhí)行平安約束。
WebFilter-用于聲明servlet過濾器的注解。
WebInitParam-用于在servlet或過濾器上聲明初始化參數(shù)的注解,在WebFilter或WebServlet上注解。
WebListener-用于在給定的Web應(yīng)用程序上下文中聲明各品種型事情的偵聽器的注解。
WebServlet-此注解用于聲明servlet的配置。
5.應(yīng)用程序開發(fā)框架(ADF,ApplicationDevelopmentFramework)和注解
如今,我們正在討論的最后一局部:應(yīng)用程序開發(fā)框架(ADF)。ADF由Oracle開發(fā),用于構(gòu)建Oracle交融應(yīng)用程序。我們?cè)?jīng)看到了優(yōu)點(diǎn)和缺陷,并且曉得如何編寫自定義注解,但是在ADF中我們能夠在哪里運(yùn)用自定義注解呢?ADF能否提供本地注解?
這些無疑是有趣的問題:但是能否存在某些限制來阻止在ADF中大范圍運(yùn)用注解?前面提到的框架(如Spring和Hibernate)運(yùn)用的AOP(面向方面的編程)。在AOP中,框架提供了為任何事情的預(yù)處置和后處置注入代碼的機(jī)制。例如,您有一個(gè)鉤子在辦法執(zhí)行之前和之后放置代碼,因而您能夠在這些中央編寫自定義代碼。ADF不運(yùn)用AOP。假如我們有任何有效的注解用例,我們可能需求經(jīng)過繼承方式。
廣州天河區(qū)珠江新城富力盈力大廈北塔2706
020-38013166(網(wǎng)站咨詢專線)
400-001-5281 (售后服務(wù)熱線)
深圳市坂田十二橡樹莊園F1-7棟
Site/ http://www.szciya.com
E-mail/ itciya@vip.163.com
品牌服務(wù)專線:400-001-5281
長沙市天心區(qū)芙蓉中路三段398號(hào)新時(shí)空大廈5樓
聯(lián)系電話/ (+86 0731)88282200
品牌服務(wù)專線/ 400-966-8830
旗下運(yùn)營網(wǎng)站:
Copyright ? 2016 廣州思洋文化傳播有限公司,保留所有權(quán)利。 粵ICP備09033321號(hào)