深入Java注解

注解的基本语法

1.四种元注解的使用说明:
深入Java注解_第1张图片

编写注解处理器

1.Java处理注解的过程如图:
深入Java注解_第2张图片
代码实例:

//注解接口类
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
    public int id();
    public String description() default "no description";
}
//使用注解的客户端类
public class PasswordUtils {
      @UseCase(id = 47, description =
      "Passwords must contain at least one numeric")
      public boolean validatePassword(String password) {
        return (password.matches("\\w*\\d\\w*"));
      }
      @UseCase(id = 48)
      public String encryptPassword(String password) {
       return new StringBuilder(password).reverse().toString();
      }
      @UseCase(id = 49, description =
      "New passwords can't equal previously used ones")
      public boolean checkForNewPassword(
        List<String> prevPasswords, String password) {
        return !prevPasswords.contains(password);
      }
    } 
    //注解处理器
public class UseCaseTracker {
      public static void
      trackUseCases(List<Integer> useCases, Class<?> cl) {
        for(Method m : cl.getDeclaredMethods()) {
          UseCase uc = m.getAnnotation(UseCase.class);
          if(uc != null) {
            System.out.println("Found Use Case:" + uc.id() +
              " " + uc.description());
            useCases.remove(new Integer(uc.id()));
          }
        }
        for(int i : useCases) {
          System.out.println("Warning: Missing use case-" + i);
        }
      }
      public static void main(String[] args) {
        List<Integer> useCases = new ArrayList<Integer>();
        Collections.addAll(useCases, 47, 48, 49, 50);
        trackUseCases(useCases, PasswordUtils.class);
      }
    } 

运行结果:
Found Use Case:47 Passwords must contain at least one numeric
Found Use Case:48 no description
Found Use Case:49 New passwords can’t equal previously used ones
Warning: Missing use case-50
2.注解元素:

  • 所有基本类型(int,float,boolean等)
  • String
  • Class
  • enum
  • Annotation
  • 以上类型的数组
    3.在hibernate,enterprise javaBean等这些技术中,常常可以用JPA注解,原理如何实现的呢?这里可以根据上面的流程写一个使用注解创捷数据库。
    代码:
//数据库表名注解接口类
@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
    //数据库表名
  public String name() default "";
} 
//数据库约束注解接口类
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraints {
    //主键
  boolean primaryKey() default false;
  //是否允许为空值
  boolean allowNull() default true;
  //设置唯一值
  boolean unique() default false;
}
//数据库字符类型的注解类
@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;
}
//使用注解类建立一个数据库
//数据库表名
@DBTable(name = "MEMBER")
public class Member {
    //数据库列名
  @SQLString(30) String firstName;
  @SQLString(50) 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 String getLastName() { return lastName; }
  public String toString() { return handle; }
  public Integer getAge() { return age; }
} 
//注解处理器
public class TableCreator {
  public static void main(String[] args) throws Exception {
    args=new String[]{"beyondboy.Member"};
    for(String className : args) {
        //获得类名
      Class<?> cl = Class.forName(className);
      //获得数据库表名接口类
      DBTable dbTable = cl.getAnnotation(DBTable.class);
      if(dbTable == null) {
        System.out.println(
          "No DBTable annotations in class " + className);
        continue;
      }
      //获得数据库表名
      String tableName = dbTable.name();
      // 如果数据库表名为空,则默认使用类名
      if(tableName.length() < 1)
        tableName = cl.getName().toUpperCase();
      //存储数据库列名
      List<String> columnDefs = new ArrayList<String>();
      for(Field field : cl.getDeclaredFields()) {
        String columnName = null;
        Annotation[] anns = field.getDeclaredAnnotations();
        //如果字段没有注解,则跳过处理
        if(anns.length < 1)
          continue; 
        //判断字段是否是Integer类型
        if(anns[0] instanceof SQLInteger) {
          SQLInteger sInt = (SQLInteger) anns[0];
          //如果列名为空,默认使用字段名
          if(sInt.name().length() < 1)
            columnName = field.getName().toUpperCase();
          else
            columnName = sInt.name();
          columnDefs.add(columnName + " INT" +
            getConstraints(sInt.constraints()));
        }
        //判断字段是否是String类型
        if(anns[0] instanceof SQLString) {
          SQLString sString = (SQLString) anns[0];
        //如果列名为空,默认使用字段名
          if(sString.name().length() < 1)
            columnName = field.getName().toUpperCase();
          else
            columnName = sString.name();
          columnDefs.add(columnName + " VARCHAR(" +
            sString.value() + ")" +
            getConstraints(sString.constraints()));
        }
        //创建数据据语句
        StringBuilder createCommand = new StringBuilder(
          "CREATE TABLE " + tableName + "(");
        for(String columnDef : columnDefs)
          createCommand.append("\n " + columnDef + ",");
        //删除最后一个逗号
        String tableCreate = createCommand.substring(
          0, createCommand.length() - 1) + ");";
        System.out.println("Table Creation SQL for " +
          className + " is :\n" + tableCreate);
      }
    }
  }
  //获得约束定义
  private static String getConstraints(Constraints con) {
    String constraints = "";
    if(!con.allowNull())
      constraints += " NOT NULL";
    if(con.primaryKey())
      constraints += " PRIMARY KEY";
    if(con.unique())
      constraints += " UNIQUE";
    return constraints;
  }
} 

运行结果:
Table Creation SQL for beyondboy.Member is :
CREATE TABLE MEMBER(
FIRSTNAME VARCHAR(30));
Table Creation SQL for beyondboy.Member is :
CREATE TABLE MEMBER(
FIRSTNAME VARCHAR(30),
LASTNAME VARCHAR(50));
Table Creation SQL for beyondboy.Member is :
CREATE TABLE MEMBER(
FIRSTNAME VARCHAR(30),
LASTNAME VARCHAR(50),
AGE INT);
Table Creation SQL for beyondboy.Member is :
CREATE TABLE MEMBER(
FIRSTNAME VARCHAR(30),
LASTNAME VARCHAR(50),
AGE INT,
HANDLE VARCHAR(30) PRIMARY KEY);
## 3.使用apt处理注解 ##

你可能感兴趣的:(java注解)