• 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 }
  • 相关阅读:
    Is LaMDA Sentient? — an Interview
    【TED演讲】为什么你应该知道你的同事得多少报酬?(中英字幕)
    炉石传说 卡牌 英文
    Springboot 指定运行时配置文件的几种方式 规格严格
    WARNING: bridgenfcalliptables is disabled解决 规格严格
    Ambari报错大全 规格严格
    CentOS7使用firewallcmd操作防火墙与端口 规格严格
    Exiting due to GUEST_MISSING_CONNTRACK: Sorry, Kubernetes 1.19.2 requires conntrack to be installed in root's path 规格严格
    如何使用Journalctl查看并操作Systemd日志 规格严格
    linux查看修改路由表route命令详解 规格严格
  • 原文地址:https://www.cnblogs.com/hangxin1940/p/2042738.html
Copyright © 2020-2023  润新知