注解##
20.1 基本语法
- 定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
public int id(); //注解的元素
public String description() default "no description";
}
标准注解:
元注解:
元注解主要是注解其他的注解。
20.2 编写注解处理器
public class UserCaseTracer {
public static void tracerUserCase(List<Integer> userCases,Class<?> c1) {
for (Method m : c1.getDeclaredMethods()) {
UseCase uc = m.getAnnotation(UseCase.class);
if(uc != null){
System.out.println("Found Use Case:" + uc.id() +
" " + uc.description());
}
userCases.remove(new Integer(uc.id()));
}
for(int i : userCases) {
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);
tracerUserCase(useCases, PasswordUtils.class);
}
}
-
注解元素
注解元素可用的类型如下:
所有的基本类型,String,Class,enum,Annotation,以上类型的数组。 -
默认值
注解元素必须有默认值,或者使用必须提供元素值。 -
生成外部文件
快捷方式:如果元素汇中有value时,并且使用注解时该元素是唯一需要赋值的,此时无需用键-值对赋值,在括号后给出值即可 @SQLString(30) 。
@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 {
// if(args.length < 1) {
// System.out.println("arguments: annotated classes");
// System.exit(0);
// }
String[] a = {"Member"};
for(String className : a) {
Class<?> cl = Class.forName("com.thinkinjava.c20.database.Member");
DBTable dbTable = cl.getAnnotation(DBTable.class);
if(dbTable == null) {
System.out.println(
"No DBTable annotations in class " + className);
continue;
}
String tableName = dbTable.name();
// If the name is empty, use the Class 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; // Not a db table column
if(anns[0] instanceof SQLInteger) {
SQLInteger sInt = (SQLInteger) anns[0];
// Use field name if name not specified
if(sInt.name().length() < 1)
columnName = field.getName().toUpperCase();
else
columnName = sInt.name();
columnDefs.add(columnName + " INT" +
getConstraints(sInt.constraints()));
}
if(anns[0] instanceof SQLString) {
SQLString sString = (SQLString) anns[0];
// Use field name if name not specified.
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 + ",");
// Remove trailing comma
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;
}
}