《java程式設計思想——第二十章(註解)》
阿新 • • 發佈:2018-11-17
註解##
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; } }