java 之 注解

注解就像javadoc的注释一样,只不过注释是静态源码级别的,而注解可以使运行时的,不但可以告诉编译器某些事,也可以用来减少工作负担。

 下面为三种标准注解以及四种元注解:

1、@Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括:
            ElemenetType.CONSTRUCTOR   构造器声明 
            ElemenetType.FIELD   域声明(包括 enum 实例) 
            ElemenetType.LOCAL_VARIABLE   局部变量声明
            ElemenetType.METHOD   方法声明
            ElemenetType.PACKAGE   包声明
            ElemenetType.PARAMETER   参数声明
            ElemenetType.TYPE   类,接口(包括注解类型)或enum声明
2、@Retention 表示在什么级别保存该注解信息。可选的 RetentionPolicy 参数包括:
            RetentionPolicy.SOURCE   注解将被编译器丢弃
            RetentionPolicy.CLASS   注解在class文件中可用,但会被VM丢弃
            RetentionPolicy.RUNTIME   VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息
3、@Documented 将此注解包含在 javadoc 中

4、@Inherited 允许子类继承父类中的注解'
5、@Deprecated  表示当前元素是不赞成使用的。
6、@Override  表示当前方法是覆盖父类的方法
7、@SuppressWarnings  表示关闭一些不当的编译器警告信息

 

下面看示例,《thinking in java 4th》中[1070]示例改的:

 

  1 import java.lang.annotation.Annotation;
  2 import java.lang.annotation.ElementType;
  3 import java.lang.annotation.Retention;
  4 import java.lang.annotation.RetentionPolicy;
  5 import java.lang.annotation.Target;
  6 import java.lang.reflect.Field;
  7 import java.util.ArrayList;
  8 import java.util.List;
  9 
 10 
 11 public class Test {
 12 
 13     @Target(ElementType.TYPE)
 14     @Retention(RetentionPolicy.RUNTIME)
 15     public @interface DBTable{
 16         public String name() default "";
 17     }
 18     
 19     //定义SQL约束注解
 20     @Target(ElementType.FIELD)//这个注解用于字段
 21     @Retention(RetentionPolicy.RUNTIME)//这个注解保留到运行时    
 22     public @interface Constraints{
 23         boolean primaryKey() default false
 24         boolean allowNull() default true
 25         boolean unique() default false;
 26     }
 27     
 28     //定义SQLString 类型注解
 29     @Target(ElementType.FIELD)
 30     @Retention(RetentionPolicy.RUNTIME)
 31     public @interface SQLString{
 32         int value() default 0;
 33         String name() default "";
 34         Constraints constraints() default @Constraints; //这是个嵌套注解,默认值就是@约束注解
 35     }
 36     
 37     //定义SQLInterger类型注解    
 38     @Target(ElementType.FIELD)
 39     @Retention(RetentionPolicy.RUNTIME)
 40     public @interface SQLInterger{
 41         String name() default "";
 42         Constraints constraints() default @Constraints;
 43     }
 44     
 45     public @interface Uniqueness{
 46         Constraints constraints() default @Constraints(unique=true); //嵌套了Consttrains注解,默认使注解的unique元素为t
 47     }
 48     
 49     
 50     
 51     //我们扩展一下,自定义SQLDate注解
 52     @Target(ElementType.FIELD)
 53     @Retention(RetentionPolicy.RUNTIME)
 54     public @interface SQLDate{
 55         String name() default "2012-01-01"//注解只允许那几中基本数据类型
 56         Constraints constraints() default @Constraints;
 57     }
 58     
 59     //这是一个java bean,包含了要往数据库写入得一个对象的所有信息
 60     @DBTable(name="MEMBER")
 61     public class Member{
 62         @SQLString(30)//为firstName注解, @SQLString ,value是30,其他为默认,firstName
 63         String firstName; 
 64         @SQLString(50)//同上,value其实是个快捷方式,如果注释只定义了value这个元素,那么赋值的时候,可以用键值对那样赋值
 65         String lastName;
 66         @SQLInterger Integer age;//同上,这里注解的所有字段为默认,名字为age
 67         //这是个内嵌元素的注解
 68         @SQLString(value=30,constraints=@Constraints(primaryKey=true))
 69         String handle;
 70         @SQLString(value=30,name="2020-10-1")
 71         String birthDay;
 72         
 73         public String getFirstName() {
 74             return firstName;
 75         }
 76 
 77         public String getLastName() {
 78             return lastName;
 79         }
 80 
 81         public Integer getAge() {
 82             return age;
 83         }
 84 
 85         public String getBirthDay() {
 86             return birthDay;
 87         }
 88 
 89         int memberCount;
 90         
 91         public String toString(){
 92             return handle;
 93         }
 94         
 95     }
 96     
 97 
 98     public static void main(String[] args) throws ClassNotFoundException{
 99         String className = "Test$Member";
100         Class<?> cl=Class.forName(className); //反射,获得类的class字节码
101         //反射出cl的注解,参数是DBTable的字节码class
102         DBTable dbTable=cl.getAnnotation(DBTable.class); 
103         String tableName=dbTable.name();
104         //这个用来存储java beans的属性
105         List<String> columnDefs=new ArrayList<String>();
106         //获取这个java beans的所有属性,这里也顺便学到java bean相关的反射
107         for(Field field:cl.getDeclaredFields()){
108             String columnName=null;
109             //获取这个java bean属性的所有注解
110             Annotation[] anns=field.getDeclaredAnnotations();
111             if(anns.length<1)
112                 continue//如果没有注解,则跳过,到下一个属性
113             //如果注解集合的第一元素是个SQLInterger注解的话
114             if(anns[0instanceof SQLInterger){
115                 SQLInterger sInt=(SQLInterger)anns[0];
116                 if(sInt.name().length()<1)
117                     //如果注解元素name没有定义名称的话,则使用属性名作为名字
118                     columnName=field.getName().toUpperCase();
119                 else
120                     //定义了的话,就用定义的东西
121                     columnName=sInt.name();
122                 columnDefs.add(columnName+" INT"+getConstraints(sInt.constraints()));                
123             }
124             //如果第一个元素是SQLString注解的话
125             if(anns[0instanceof SQLString ){
126                 SQLString sString=(SQLString) anns[0];
127                 if(sString.name().length()<1)
128                     columnName=field.getName().toUpperCase();
129                 else
130                     columnName=sString.name();
131                 columnDefs.add(columnName+" VARCHAR("+sString.value()+")"+getConstraints(sString.constraints()));
132             }            
133         }
134 
135         //下面模拟创建表
136         StringBuilder createCommand=new StringBuilder("CREATE TABLE "+tableName+"(");
137         for(String columnDef:columnDefs)
138             createCommand.append("\n    "+columnDef+".");
139         String tableCreate=createCommand.substring(0,createCommand.length()-1)+");";
140         System.out.println("Table Cration SQL for "+className+" is:\n"+tableCreate);
141         
142     }
143     
144     //获得约束
145     private static String getConstraints(Constraints con){
146         String constraints="";
147         if(!con.allowNull()) //如果约束不允许使用空值
148             constraints +=" NOT NULL";
149         if(con.primaryKey())//如果是主键
150             constraints+=" PRIMARY KEY";
151         if(con.unique())
152             constraints+=" UNIQUE";
153         return constraints;            
154     }
155     
156     
157 }

 

posted on 2011-05-11 00:00  黑暗伯爵  阅读(916)  评论(0编辑  收藏  举报

导航