关于java的注解

来源:互联网 发布:什么工具代替淘宝指数 编辑:程序博客网 时间:2024/05/20 11:26

     1.0

   @Target(ElementType.METHOD)   @Retention(RetentionPolicy.RUNTIME)   public @interface UseCase {       public int id();       public String description() default "no description";   }
     上面的代码就是一个简单注解示例。可以看到他的上面还有两个注解,如果全部算上,其实还有两个,@Document和@Inherited。他们各自的使用方式和作用如下

@Target表示注解可以使用的位置,值为java中的枚举类ElementType。一般使用下面几个
a. CONSTRUCTOR 构造器的声明
b. Field :域声明(这个域就是值得类里面的各个创建的属性)
c. LOCAL_VARIABLE:局部变量声明
d. METHOD :方法声明
e. PARAMETER : 方法声明
f. TYPE : 类,接口或者枚举类(enum)的声明
@Retention表示在什么级别保存该注解信息,可选的RetentionPolicy参数包括:
a. SOURCE : 注解将被编译器丢弃
b. CLASS :注解将在class文件中用,单被VM丢弃
c. RUNTIME : VM也会保留注解,所以能够通过反射机制读取注解信息@Document注解将被包含在doc文件中@Inherited允许子类继承父类中的注解

   注解可用的元素有String,所有的基本类型(int,float,boolean),Class,enum,Annotation 以及他们的数组。也就是说不能在注解中使用自己定义的类或者大多数的java类。

  下面是个简单的使用注解获取反射信息的dbsql生成String的类:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface DBTable {      String name() default "";}
@DBTable(name = "MEMBER")public class Member {    @SQLString(30)    String firstName;    @SQLString(50)    @SQLInteger    String lastName;    @SQLInteger    Integer age;    @SQLString(value=30,constraints = @Constraints(primaryKey = true))    String handle;    static int memberCount;    public String getHandle(){        return handle;    }    public String getFirstName() {        return firstName;    }    public void setFirstName(String firstName) {        this.firstName = firstName;    }    public String getLastName() {        return lastName;    }    public void setLastName(String lastName) {        this.lastName = lastName;    }    public Integer getAge() {        return age;    }    public void setAge(Integer age) {        this.age = age;    }    public void setHandle(String handle) {        this.handle = handle;    }    public static int getMemberCount() {        return memberCount;    }    public static void setMemberCount(int memberCount) {        Member.memberCount = memberCount;    }}

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface SQLString {    int value() default 0;    String name() default "";    Constraints constraints() default @Constraints();}@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface SQLInteger {    String name() default "";    Constraints constraints() default @Constraints;}


public class TableCreator {    public static void main(String agrs[]) throws ClassNotFoundException {      //通过名字得到Member的class文件,用于反射获取类中的属性(域),这里的类名(Member)一定要加上包名,不然找不到      Class<?> clazz=Class.forName("Member");        DBTable dbTable=clazz.getAnnotation(DBTable.class);        if(dbTable==null){            System.out.println("请输入正确的带注解的类");            System.exit(0);        }        String tableName=dbTable.name();        List<String> colNumbers=new ArrayList<String>();      //将获取到的域进行处理        for(Field field:clazz.getDeclaredFields()){            String columnName=null;            //感觉注解最后是用的代理实现的            Annotation[] annotations=field.getDeclaredAnnotations();            if(annotations.length<1){                System.out.println("当前没有注解");               // System.exit(0);            }else {//因为只有一个注解,所以用0,多个可以多个处理                if (annotations[0] instanceof SQLString) {                       SQLString sString = (SQLString) annotations[0];                    if (sString.name().length() < 1) {                        columnName = field.getName().toUpperCase();                    } else {                        columnName = sString.name();                    }                    colNumbers.add(columnName + " VARCHAR(" + sString.value() + ")" + getConstraints(sString.constraints()));                }                if (annotations[0] instanceof SQLInteger) {                    SQLInteger sSQLInteger = (SQLInteger) annotations[0];                    if (sSQLInteger.name().length() < 1) {                        columnName = field.getName().toUpperCase();//获取当前属性名称                    } else {                        columnName = sSQLInteger.name();                    }                    colNumbers.add(columnName + " INT " + getConstraints(sSQLInteger.constraints()));                }            }        }        StringBuilder sb=new StringBuilder("CREATE TABLE "+tableName+" (");        for(String col:colNumbers){            sb.append("\n  "+col+",");        }        String table=sb.substring(0,sb.length()-1)+" );";        System.out.println(table);    }    private static String getConstraints(Constraints constraints){        String cs="";        if(!constraints.allNull()){            cs+=" NOT Null";        }        if(constraints.primaryKey()){            cs+=" PRIMARY KEY";        }        if(constraints.unique()){            cs+=" UNIQUE";        }        return cs;    }}

最后运行的结果为:

当前没有注解   

CREATE TABLE MEMBER (
  FIRSTNAME VARCHAR(30),
  LASTNAME VARCHAR(50),
  AGE INT ,
  HANDLE VARCHAR(30) PRIMARY KEY );


因为memberCount没有注解,所以会进入打印的方法中,其他带注解的都成功被反射出来。

感觉这是个后台自动生成sql查询语句的办法,以后抽时间写一个



最后,以上的内容主要来自于java编程思想和我的一些注解,如有不对的地方,忘指正。





原创粉丝点击