日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JDK5--Annotation学习:基础(二)

發布時間:2024/4/14 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JDK5--Annotation学习:基础(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載自:http://www.iteye.com/topic/1123823

引述要學習Spring框架的技術內幕,必須事先掌握一些基本的Java知識,正所謂“登高必自卑,涉遠必自邇”。以下幾項Java知識和Spring框架息息相關,不可不學(我將通過一個系列分別介紹這些Java基礎知識,希望對大家有所幫助。):

[1] Java反射知識-->Spring IoC :http://www.iteye.com/topic/1123081
[2] Java動態代理-->Spring AOP :http://www.iteye.com/topic/1123293
[3] 屬性編輯器,即PropertyEditor-->Spring IoC:http://www.iteye.com/topic/1123628
[4] XML基礎知識-->Spring配置:http://www.iteye.com/topic/1123630
[5] 注解-->Spring配置:http://www.iteye.com/topic/1123823
[6] 線程本地變更,即ThreadLocal-->Spring事務管理:http://www.iteye.com/topic/1123824
[7] 事務基礎知識-->Spring事務管理:http://www.iteye.com/topic/1124043
[8] 國際化信息-->MVC:http://www.iteye.com/topic/1124044
[9] HTTP報文-->MVC:http://www.iteye.com/topic/1124408



有必要對JDK 5.0新增的注解(Annotation)技術進行簡單的學習,因為Spring 支持@AspectJ,而@AspectJ本身就是基于JDK 5.0的注解技術。所以學習JDK 5.0的注解知識有助于我們更好地理解和掌握Spring的AOP技術。

了解注解

對于Java開發人員來說,在編寫代碼時,除了源程序以外,我們還會使用Javadoc標簽對類、方法或成員變量進行注釋,以便使用Javadoc工具生成和源代碼配套的Javadoc文檔。這些@param、@return等Javadoc標簽就是注解標簽,它們為第三方工具提供了描述程序代碼的注釋信息。使用過Xdoclet的朋友,對此將更有感觸,像Struts、Hibernate都提供了Xdoclet標簽,使用它們可以快速地生成對應程序代碼的配置文件。

JDK5.0注解可以看成是Javadoc標簽和Xdoclet標簽的延伸和發展。在JDK5.0中,我們可以自定義這些標簽,并通過Java語言的反射機制中獲取類中標注的注解,完成特定的功能。
注解是代碼的附屬信息,它遵循一個基本原則:注解不能直接干擾程序代碼的運行,無論增加或刪除注解,代碼都能夠正常運行。Java語言解釋器會忽略這些注解,而由第三方工具負責對注解進行處理。第三方工具可以利用代碼中的注解間接控制程序代碼的運行,它們通過Java反射機制讀取注解的信息,并根據這些信息更改目標程序的邏輯,而這正是Spring AOP對@AspectJ提供支持所采取的方法。

引用 很多東西的設計都必須遵循最基本的原則,為了防止機器人傷害人類,科幻作家阿西莫夫于1940年提出了“機器人三原則”:第一,機器人不能傷害人類;第二,機器人應遵守人類的命令,與第一條違背的命令除外;第三,機器人應能保護自己,與第一條違背的命令除外。這是給機器人賦予的倫理性綱領,機器人學術界一直將這三條原則作為機器人開發的準則。



一個簡單的注解類

通常情況下,第三方工具不但負責處理特定的注解,本身還提供了這些注解的定義,所以我們通常僅需關注如何使用注解就可以了。但定義注解類本身并不困難,Java提供了定義注解的語法。下面,我們馬上著手編寫一個簡單的注解類,如代碼清單7-1所示:

代碼清單7-1? NeedTest注解類

Java代碼 ?

?

package com.baobaotao.aspectj.anno; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME) //①聲明注解的保留期限 @Target(ElementType.METHOD)//②聲明可以使用該注解的目標類型 public @interface NeedTest {//③定義注解boolean value() default true;//④聲明注解成員 }



Java新語法規定使用@interface修飾符定義注解類,如③所示,一個注解可以擁有多個成員,成員聲明和接口方法聲明類似,這里,我們僅定義了一個成員,如④所示。成員的聲明有以下幾點限制:

  • 成員以無入參無拋出異常的方式聲明,如boolean value(String str)、boolean value() throws Exception等方式是非法的;
  • 可以通過default為成員指定一個默認值,如String level() default "LOW_LEVEL"、int high() default 2是合法的,當然也可以不指定默認值;
  • 成員類型是受限的,合法的類型包括原始類型及其封裝類、String、Class、enums、注解類型,以及上述類型的數組類型。如ForumService value()、List foo()是非法的。



在①和②處,我們所看到的注解是Java預定義的注解,稱為元注解(Meta-Annotation),它們被Java編譯器使用,會對注解類的行為產生影響。@Retention(RetentionPolicy. RUNTIME)表示NeedTest這個注解可以在運行期被JVM讀取,注解的保留期限類型在java.lang.annotation.Retention類中定義,介紹如下:

  • SOURCE:注解信息僅保留在目標類代碼的源碼文件中,但對應的字節碼文件將不再保留;
  • CLASS:注解信息將進入目標類代碼的字節碼文件中,但類加載器加載字節碼文件時不會將注解加載到JVM中,也即運行期不能獲取注解信息;
  • RUNTIME:注解信息在目標類加載到JVM后依然保留,在運行期可以通過反射機制讀取類中注解信息。 ??

?Target(ElementType.METHOD)表示NeedTest這個注解只能應用到目標類的方法上,注解的應用目標在java.lang.annotation.ElementType類中定義:

  • TYPE:類、接口、注解類、Enum聲明處,相應的注解稱為類型注解;
  • FIELD:類成員變量或常量聲明處,相應的注解稱為域值注解;
  • METHOD:方法聲明處,相應的注解稱為方法注解;
  • PARAMETER:參數聲明處,相應的注解稱為參數注解;
  • CONSTRUCTOR:構造函數聲明處,相應的注解稱為構造函數注解;
  • LOCAL_VARIABLE:局部變量聲明處,相應的注解稱為局域變量注解;
  • ANNOTATION_TYPE:注解類聲明處,相應的注解稱為注解類注解,ElementType. TYPE包括ElementType.ANNOTATION_TYPE;
  • PACKAGE:包聲明處,相應的注解稱為包注解。



如果注解只有一個成員,則成員名必須取名為value(),在使用時可以忽略成員名和賦值號(=),如@NeedTest(true)。注解類擁有多個成員時,如果僅對value成員進行賦值則也可不使用賦值號,如果同時對多個成員進行賦值,則必須使用賦值號,如DeclareParents (value = "NaiveWaiter", defaultImpl = SmartSeller.class)。注解類可以沒有成員,沒有成員的注解稱為標識注解,解釋程序以標識注解存在與否進行相應的處理;此外,所有的注解類都隱式繼承于java.lang.annotation.Annotation,但注解不允許顯式繼承于其他的接口。

我們希望使用NeedTest注解對業務類的方法進行標注,以便測試工具可以根據注解情況激活或關閉對業務類的測試。在編寫好NeedTest注解類后,就可以在其他類中使用它了。

使用注解

我們在ForumService中使用NeedTest注解,標注業務方法是否需要測試,如代碼清單7-2所示:

代碼清單7-2? ForumService:使用注解

Java代碼 ? package com.baobaotao.aspectj.anno; public class ForumService {@NeedTest(value=true) ①public void deleteForum(int forumId){System.out.println("刪除論壇模塊:"+forumId);}@NeedTest(value=false) ②public void deleteTopic(int postId){System.out.println("刪除論壇主題:"+postId);} }



如果注解類和目標類不在同一個包中,需要通過import引用的注解類。在①和②處,我們使用NeedTest分別對deleteForum()和deleteTopic()方法進行標注。在標注注解時,可以通過以下格式對注解成員進行賦值:

引用 @<注解名>(<成員名1>=<成員值1>,<成員名1>=<成員值1>,...)



如果成員是數組類型,可以通過{}進行賦值,如boolean數組的成員可以設置為{true,false,true}。下面是幾個注解標注的例子:

示例1,多成員的注解:

Java代碼 ? @AnnoExample(id= 2868724, synopsis = "Enable time-travel", engineer = "Mr. Peabody",date = "4/1/2007")



示例2,一個成員的注解,成員名為value。可以省略成員名和賦值符號:

Java代碼 ? @Copyright("2011 bookegou.com All Right Reserved")



示例3,無成員的注解:

Java代碼 ? @Override



示例4,成員為字符串數組的注解:

Java代碼 ? @SuppressWarnings(value={"unchecked","fallthrough"})



示例5,成員為注解數組類型的注解:

Java代碼 ? @Reviews({@Review(grade=Review.Grade.EXCELLENT,reviewer="df"), @Review(grade=Review.Grade.UNSATISFACTORY,reviewer="eg", comment="This method needs an @Override annotation")})



@Reviews注解擁有一個@Review注解數組類型的成員,@Review注解類型有三個成員,其中reviewer、comment都是String類型,但comment有默認值,grade是枚舉類型的成員。

由于NeedTest注解的保留限期是RetentionPolicy.RUNTIME類型,因此當ForumService被加載到JVM時,仍就可通過反射機制訪問到ForumService各方法的注解信息。

訪問注解

前面提到過,注解不會直接影響程序的運行,但是第三方程序或工具可以利用代碼中的注解完成特殊的任務,間接控制程序的運行。對于RetentionPolicy.RUNTIME保留期限的注解,我們可以通過反射機制訪問類中的注解。

在JDK5.0里,Package、Class、Constructor、Method以及Field等反射對象都新增了訪問注解信息的方法:<T extends Annotation>T getAnnotation(Class<T> annotationClass),該方法支持通過泛型直接返回注解對象。

下面,我們就通過反射來訪問注解,得出ForumService 類中通過@NeedTest注解所承載的測試需求,如代碼清單7-3所示:

代碼清單7-3? TestTool:訪問代碼中的注解

Java代碼 ?

??

package com.baobaotao.aspectj.anno; import java.lang.reflect.Method; public class TestTool {public static void main(String[] args) {//①得到ForumService對應的Class對象Class clazz = ForumService.class; //②得到ForumSerivce對應的Method數組Method[] methods = clazz.getDeclaredMethods(); System.out.println(methods.length);for (Method method : methods) {//③獲取方法上所標注的注解對象NeedTest nt = method.getAnnotation(NeedTest. class);if (nt != null) {if (nt.value()) {System.out.println(method.getName() + "()需要測試");} else {System.out.println(method.getName() + "()不需要測試");}}}} }



在③處,通過方法的反射對象,我們獲取了方法上所標注的NeedTest注解對象,接著就可以訪問注解對象的成員,從而得到ForumService類方法的測試需求。運行以上代碼,輸出以下的信息:

引用 deleteForum()需要測試
deleteTopic()不需要測試

總結

以上是生活随笔為你收集整理的JDK5--Annotation学习:基础(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。