随笔 - 81  文章 - 1033  trackbacks - 0
<2007年1月>
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910

在浮躁的年代里,我们进取心太切,患得患失;虚荣心太强,战战兢兢。一心争强好胜,惟恐榜上无名。
I think I can fly , and flying like a bird !
程序员一名,已售出,缺货中!

我的邮件联系方式

用且仅用于MSN

博客点击率
free web counter
free web counter

常用链接

留言簿(36)

随笔档案

搜索

  •  

积分与排名

  • 积分 - 186100
  • 排名 - 309

最新评论

阅读排行榜

评论排行榜

在创建EJB组件时,必需提供一些定义,使得EJB组件使用一些服务例如:安全服务,持久化服务,事务服务。EJB容器可以提供这些服务,这样EJB只要实现业务逻辑就可以了。但是说到底EJB容器使用EJB组件的元数据来提供这些服务,在以前EJB的元数据是以XML配置文件形式出现的,这些配置文件与EJB源文件是分开的。
EJB的部署人员无法了解EJB本身的信息,如果EJB组件的创建者用注释(Annotation)的方法将这些配置服务的信息和代码放在一起,这样EJB的部署者就可以了解EJB的信息,EJB的home接口可以使用Annotation自动生成,当然到目前为止更好的是在简单的Java Object上使用Annotations。

一 什么是Annotation

在已经发布的JDK1.5(tiger)中增加新的特色叫 Annotation。Annotation提供一种机制,将程序的元素如:类,方法,属性,参数,本地变量,包和元数据联系起来。这样编译器可以将元数据存储在Class文件中。这样虚拟机和其它对象可以根据这些元数据来决定如何使用这些程序元素或改变它们的行为。

二 定义一个简单的Annotation并使用它

1.定义Annotation

定义一个Annotation是什么简单的,它采取的是类似于Interface的定义方式: “@+annotation类型名称+(..逗号分割的name-value对...)”

代码
  1. //Example 1   
  2.   
  3. package  sz.starbex.bill.annotation;   
  4.   
  5. import  java.lang.annotation.Retention;   
  6.   
  7. import  java.lang.annotation.RetentionPolicy;   
  8.   
  9. import  java.lang.annotation.Target;   
  10.   
  11. import  java.lang.annotation.ElementType;   
  12.   
  13. @Retention (RetentionPolicy.RUNTIME)   
  14.   
  15. @Target (ElementType.METHOD)   
  16.   
  17. public   @interface  SimpleAnnotation {   
  18.   
  19. String value();   
  20.   
  21. }  

@Retention这个meta-annotation表示我们创建的SimpleAnnotation这个Annotation将会存储在Class文件中,并在java

VM运行时加载它。@Target这个meta-annotation表示我们创建的SimplwAnnotation将会为描述方法,而@interface SimpleAnnotation是我们自定义的Annotation,它有一个成员叫value,返回值是String。

2.使用Annotation

代码
  1. //Example 2   
  2.   
  3. package  sz.starbex.bill.annotation;   
  4.   
  5. import  sz.starbex.bill.annotation.SimpleAnnotation;   
  6.   
  7. public   class  UsingSimpleAnnotation {   
  8.   
  9. @SimpleAnnotation (value= "Pass:This method will Pass" ) //注意name=value的用法   
  10.   
  11. public   void  pass(){   
  12.   
  13. if ( 10 > 5 ) System.out.println( "测试通过" );   
  14.   
  15. }   
  16.   
  17. @SimpleAnnotation ( "Fail:This method will Fail" ) //注意name=value的用法   
  18.   
  19. public   void  fail(){   
  20.   
  21. if ( 10 < 5 ) System.out.println( "测试失败" );   
  22.   
  23. }   
  24.   
  25. }  

一个Annotation用于程序元素(在本例中是method),在method方法之前用(@Annotation名称(name=value,name=value.....)。在本例中是@SimpleAnnotation(value="Pass:This method will Pass")。每个annotation具有一个名字和成员个数>=0,当只有一个单一的成员时,这个成员就是value。我们也可以这样写 @SimpleAnnotation("Fail:This method will Fail")。至此@SimpleAnnotation将Pass和Fail联系起来了。

3.在运行时访问Annotation

一旦Annotation与程序元素联系起来,我们可以通过反射访问它们并可以取得它们的值。我们使用一个新的interface:java.lang.reflect.AnnotatedElement。java.lang.reflect.AnnotatedElement接口中的方法有:

a. boolean isAnnotationPresent(Class annotationType)

如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。
b. T getAnnotation(Class annotationType)

如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
c. Annotation[] getAnnotations()

返回此元素上存在的所有注释。
d. Annotation[] getDeclaredAnnotations()

返回直接存在于此元素上的所有注释。
你要注意 isAnnotationPresent和getAnnotation方法,它们使用了Generics,请参考我的Java 范型的Blog。

下面我们列出一些实现了AnnotatedElement 接口的类

1. java.lang.reflect.AccessibleObject

2. java.lang.Class

3. java.lang.reflect.Constructor

4. java.lang.reflect.Field

5. java.lang.reflect.Method

6. java.lang.Package

下面的Example程序说明了如何在运行环境访问Annotation

代码
  1. package  sz.starbex.bill.annotation;   
  2.   
  3. import  sz.starbex.bill.annotation.SimpleAnnotation;   
  4.   
  5. import  java.lang.reflect.Method;   
  6.   
  7. public   class  SimpleAccessAnnotation {   
  8.   
  9. static   void  accessAnnotationTest(Class usingAnnnotationClass){   
  10.   
  11. try  {   
  12.   
  13. //Object usingAnnnotationClass=Class.forName(usingAnnotationClassName).newInstance();   
  14.   
  15. Method [] methods=usingAnnnotationClass.getDeclaredMethods(); //取得对方法   
  16.   
  17. for (Method method:methods){   
  18.   
  19. System.out.println(method.getName());   
  20.   
  21. SimpleAnnotation    
  22.   
  23. simpleAnnotation=method.getAnnotation(SimpleAnnotation. class ); //得到方法的Annotation   
  24.   
  25. if (simpleAnnotation!= null ){   
  26.   
  27. System.out.print(simpleAnnotation.value()+ "==" );   
  28.   
  29. String result=invoke(method,usingAnnnotationClass);   
  30.   
  31. System.out.println(result);   
  32.   
  33. }   
  34.   
  35. }   
  36.   
  37. catch  (Exception e) {   
  38.   
  39. // TODO Auto-generated catch block   
  40.   
  41. e.printStackTrace();   
  42.   
  43. }   
  44.   
  45. }   
  46.   
  47. static  String invoke(Method m, Object o) {   
  48.   
  49. String result =  "passed" ;   
  50.   
  51. try  {   
  52.   
  53. m.invoke(m, new  Object[]{});   
  54.   
  55. catch  (Exception e) {   
  56.   
  57. // TODO Auto-generated catch block   
  58.   
  59. result =  "failed" ;   
  60.   
  61. }   
  62.   
  63. return  result;   
  64.   
  65. }   
  66.   
  67. /**  
  68. * @param args  
  69. */   
  70.   
  71. public   static   void  main(String[] args) {   
  72.   
  73. // TODO Auto-generated method stub   
  74.   
  75. accessAnnotationTest(UsingSimpleAnnotation. class );   
  76.   
  77. }   
  78.   
  79. }  

Java 中的Annotation的定义

Java中的Annotation

Java定义了几个标准的meta-annotation,在新Package中java.lang.annotation 中包含了以下meta-annotation:

meta-annotation 说明

@Target

1. annotation的target是一个被标注的程序元素。target说明了annotation所修饰的对象范围:annotation可被用于packages、types(类、接口、枚举、annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在annotation类型的声明中使用了target可更加明晰其修饰的目标。

meta-annotation 说明
@Target 1. annotation的target是一个被标注的程序元素。target说明了annotation所修饰的对象范围:annotation可被用于packages、types(类、接口、枚举、annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在annotation类型的声明中使用了target可更加明晰其修饰的目标。

2. ElementType的定义

TYPE// Class, interface, or enum (but not annotation)
FIELD// Field (including enumerated values)

METHOD// Method (does not include constructors)

PARAMETER// Method parameter

CONSTRUCTOR// Constructor

LOCAL_VARIABLE// Local variable or catch clause

ANNOTATION_TYPE// Annotation Types (meta-annotations)

PACKAGE// Java package
@Retention

1. SOURCE//按照规定使用注释,但是并不将它保留到编译后的类文件中

2. CLASS//将注释保留在编译后的类文件中,但是在运行时忽略它

3. RUNTIME//将注释保留在编译后的类文件中,并在第一次加载类时读取它

@Documented Documented 表示注释应该出现在类的 Javadoc 中

@Inherited 一个Annotation将被继承

三个标准的Annotation 在java.lang包中:

@Deprecated 对不再使用的方法进行注释
@Override 指明注释的方法覆盖超类的方法
@SuppressWarnings 阻止编译器的警告,例:当类型不安全时

下例来说明这三个标准的Annotation:

代码
  1. package  sz.starbex.bill.annotation;   
  2.   
  3. import  java.util.ArrayList;   
  4.   
  5. import  java.util.List;   
  6.   
  7. public   class  SimpleOverrideAnnotation {   
  8.   
  9. public   static   void  main(String[] args) {   
  10.   
  11. SimpleOverrideAnnotation test =  new  SimpleOverrideAnnotation();   
  12.   
  13. System.out.println(test.toString());   
  14.   
  15. }   
  16.   
  17. @Override   
  18.   
  19. public  String toString() {   
  20.   
  21. return   "自己的类自己输出" ;   
  22.   
  23. }   
  24.   
  25. @Deprecated   
  26.   
  27. public   void  doSomething() {   
  28.   
  29. System.out.println( "方法已过时"  );   
  30.   
  31. }   
  32.   
  33. @SuppressWarnings (value={ "unchecked" })   
  34.   
  35. public   void  testSuppressWarnings(){   
  36.   
  37. List testList= new  ArrayList();   
  38.   
  39. testList.add( "KKKK" ); //没有使用范型,类型不安全   
  40.   
  41. }   
  42.   
  43. }  

二、Annotation使用实例

一个组合的Annotation,注释类的

a. 商标Annotation

代码
  1. package  sz.starbex.bill.annotation;   
  2.   
  3. public   @interface  Trademark {   
  4.   
  5. String name();   
  6.   
  7. String owner();   
  8.   
  9. }   

b.License的annotation

代码
  1. package  sz.starbex.bill.annotation;   
  2.   
  3. import  java.lang.annotation.*;   
  4.   
  5. @Retention (RetentionPolicy.RUNTIME)   
  6.   
  7. @Target ({ElementType.TYPE, ElementType.PACKAGE})   
  8.   
  9. public   @interface  License {   
  10.   
  11. String name();   
  12.   
  13. String notice();   
  14.   
  15. boolean  redistributable();   
  16.   
  17. Trademark[] trademarks();   
  18.   
  19. }   

c.测试类

代码
  1. package  sz.starbex.bill.annotation;   
  2.   
  3. @License (name= "Bill" ,   
  4.   
  5. notice= "许可证" ,   
  6.   
  7. redistributable= true ,   
  8.   
  9. trademarks={ @Trademark (name= "Mercedes" ,owner= "Swedish" ),   
  10.   
  11. @Trademark (name= "Daewoo" ,owner= "Korean" )   
  12.   
  13. }    
  14.   
  15. )   
  16.   
  17. public   class  TestLicenseAnnotation {   
  18.   
  19. public   static   void  main(String[] args) {   
  20.   
  21. TestLicenseAnnotation test= new  TestLicenseAnnotation();   
  22.   
  23. License license=test.getClass().getAnnotation(License. class );   
  24.   
  25. System.out.println( "License发放人:" +license.name());   
  26.   
  27. System.out.println( "License注意事项:" +license.notice());   
  28.   
  29. System.out.println( "License许可:" +license.redistributable());   
  30.   
  31. Trademark [] marks=license.trademarks();   
  32.   
  33. for (Trademark mark:marks){   
  34.   
  35. System.out.println( "商标名称:" +mark.name());   
  36.   
  37. System.out.println( "商标的使用者:" +mark.owner());   
  38.   
  39. }   
  40.   
  41. }   
  42.   
  43. }    
  44.   

from:http://java.chinaitlab.com/EJB/519586_2.html



posted on 2007-01-22 22:26 cresposhi 阅读(959) 评论(6)  编辑  收藏

FeedBack:
# re: 什么是Annotation?【转载】 2007-02-01 14:39 梅颖
转的也坐哈沙发,呵呵  回复  更多评论
  
# re: 什么是Annotation?【转载】 2007-02-01 14:57 施伟
呵呵,看来你无处不在列!  回复  更多评论
  
# re: 什么是Annotation?【转载】 2007-02-01 16:21 梅颖
呜呜。。  回复  更多评论
  
# re: 什么是Annotation?【转载】 2007-02-01 21:46 施伟
哭什么啊,谁欺负你了啊?  回复  更多评论
  
# re: 什么是Annotation?【转载】 2007-02-02 15:14 梅颖
同事。。。  回复  更多评论
  
# re: 什么是Annotation?【转载】 2007-02-02 20:41 施伟
好,我等会帮你檄文讨伐  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: