package _20.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
public class TableCreator {
public static void main(String[] args) {
try {
// if(args.length < 1) {
// System.out.println("arguments length incorrect!");
// System.exit(0);
// }
String arr[] = new String[] {"_20.annotation.Member"};
for (String clName : arr) {
Class<?> cl = Class.forName(clName);
DBTable dbTable = cl.getAnnotation(DBTable.class);
if(dbTable == null) {
System.out.println("NO DBTABLE ANNOTATION IN CLASS " + cl.getSimpleName());
continue;
}
String tbName = dbTable.name();
tbName = tbName.length() < 1 ? cl.getName().toUpperCase() : tbName;
List<String> columnDefs = new ArrayList<String>();
for(Field field : cl.getDeclaredFields()) {
String columnName = null;
Annotation[] anns = field.getAnnotations();
if(anns.length > 0) {
if(anns[0] instanceof SQLInteger) {
SQLInteger sInt = (SQLInteger)anns[0];
columnName = sInt.name().length() < 1 ? field.getName() : sInt.name();
columnDefs.add(columnName + " INT " + getConstraints(sInt.constraints()));
}
if(anns[0] instanceof SQLString) {
SQLString str = (SQLString)anns[0];
columnName = str.name().length() < 1 ? field.getName() : str.name();
columnDefs.add(columnName + " VARCHAR(" + str.value() + ") " + getConstraints(str.constraints()));
}
if(anns[0] instanceof SQLDate) {
SQLDate sd = (SQLDate)anns[0];
columnName = sd.name().length() < 1 ? field.getName() : sd.name();
columnDefs.add(columnName + " DATE " + getConstraints(sd.constraints()));
}
}
StringBuilder sb = new StringBuilder("CREATE TABLE " + tbName + "(");
for (String columnDef : columnDefs) {
sb.append("\n " + columnDef + ",");
}
String tableCreate = sb.substring(0, sb.length() - 1) + ");";
System.out.println("Table Creation SQL for " + clName + " is: \n" + tableCreate);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getConstraints(Constraints cons) {
String constraints = "";
if(!cons.allowNull()) {
return constraints += " NOT NULL";
}
if(cons.primaryKey()) {
return constraints += " PRIMARY KEY";
}
if(cons.unique()) {
return constraints += " UNIQUE";
}
return constraints;
}
}
// 表示当前方法将覆盖超类中的方法,如果书写错误,编译器会给出提示 @Override /** * 用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。 * 在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告 */ @Deprecated /** * 指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。 * 注意,在给定元素中取消显示的警告集是所有包含元素中取消显示的警告的超集。 * 例如,如果注释一个类来取消显示某个警告,同时注释一个方法来取消显示另一个警告,那么将在此方法中同时取消显示这两个警告。 * 根据风格不同,程序员应该始终在最里层的嵌套元素上使用此注释,在那里使用才有效。如果要在特定的方法中取消显示某个警告,则应该注释该方法而不是注释它的类。 */ @SuppressWarnings
1.注解(元数据)为我们在代码中添加信息提供了一种形式化的方法。
2.同时也是对C#中的一些相关性质的回应(eg:override)
3.java.lang中自带三种标准注解以及四种原注解(描述注解的注解)
/**
* 表示该注解可以用于什么地方,可能的ElementType参数包括
TYPE,
类,接口(包括注释类型),或者enum类型
FIELD,
域声明(包括enum实例)
METHOD,
方法声明
PARAMETER,
参数声明
CONSTRUCTOR,
构造器的声明
LOCAL_VARIABLE,
局部变量的声明
ANNOTATION_TYPE,
注解类型
PACKAGE
包声明
}
*/
@Target
/**
* 表示需要什么级别保存注解的信息。可选的RetentionPolicy参数包括:
*
SOURCE,
注解将被编译器丢弃
CLASS,
注解将被VM丢弃,但在class文件中可用
RUNTIME
VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息
*/
@Retention
/**
* 将此注解包含在JAVADOC中
*/
@Documented
/**
* 允许子类继承父类中的注解
*/
@Inherited
5.简单的JAVA CODE ABOUT ANNOTATION
package _20.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
public String name() default "";
}
package _20.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraints {
boolean primaryKey() default false;
boolean allowNull() default true;
boolean unique() default false;
}
package _20.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLInteger {
String name() default "";
Constraints constraints() default @Constraints(unique = true);
}
package _20.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLString {
int value() default 0;
String name() default "";
Constraints constraints() default @Constraints;// 默认是一个Constraints注解,注解嵌套
}
package _20.annotation;
import java.util.Date;
@DBTable(name = "MEMBER")
public class Member {
@SQLString(30)
private String firstName;
@SQLString(50)
private String lastName;
@SQLInteger(name = "age", constraints = @Constraints(unique = false))
Integer age;
@SQLString(value = 30, constraints = @Constraints(primaryKey = true))
String handle;
@SQLDate
Date birthday;
static int memberCount;
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public Integer getAge() {
return age;
}
public String getHandle() {
return handle;
}
@Override
public String toString() {
return handle;
}
}
6.使用APT处理注解.
package _20.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface ExtractInterface {
public String value();
}
package _20.annotation;
import java.io.PrintWriter;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.MethodDeclaration;
import com.sun.mirror.declaration.ParameterDeclaration;
import com.sun.mirror.declaration.TypeDeclaration;
/**
* 注解处理器类
* @author zhy
*
*/
public class InterfaceExtractProcessor implements AnnotationProcessor {
private final AnnotationProcessorEnvironment env;
private ArrayList<MethodDeclaration> interfaceMethods = new ArrayList<MethodDeclaration>();
public InterfaceExtractProcessor(AnnotationProcessorEnvironment env) {
this.env = env;
}
@Override
public void process() {
try {
for (TypeDeclaration td : env.getSpecifiedTypeDeclarations()) {
ExtractInterface annot = td.getAnnotation(ExtractInterface.class);
if(annot == null) break;
for(MethodDeclaration md : td.getMethods()) {
if(md.getModifiers().contains(Modifier.PUBLIC) && !md.getModifiers().contains(Modifier.STATIC)) {
interfaceMethods.add(md);
}
if(interfaceMethods.size() > 0) {
PrintWriter pw = env.getFiler().createSourceFile(annot.value());
pw.println("package " + td.getPackage().getQualifiedName() + ";");
pw.println("public interface " + annot.value() + " {");
for (MethodDeclaration md1 : interfaceMethods) {
pw.println(" public ");
pw.println(md1.getReturnType() + " ");
pw.println(md1.getSimpleName() + " ");
int i = 0;
for (ParameterDeclaration pd : md1.getParameters()) {
pw.print(pd.getType() + " " + pd.getSimpleName());
if(++i < md1.getParameters().size()) {
pw.print(", ");
}
}
pw.println(");");
}
pw.println("}");
pw.close();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package _20.annotation;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.apt.AnnotationProcessorFactory;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;
public class InterfaceExtractProcessorFactory implements AnnotationProcessorFactory {
@Override
public AnnotationProcessor getProcessorFor(
Set<AnnotationTypeDeclaration> arg0,
AnnotationProcessorEnvironment arg1) {
return new InterfaceExtractProcessor(arg1);
}
@Override
public Collection<String> supportedAnnotationTypes() {
return Collections.singleton("_20.annotation.ExtractInterface");
}
@Override
public Collection<String> supportedOptions() {
return Collections.emptySet();
}
}
http://www.marsclan.org/html/experiment/document/convention/CodeConventions_V1.0.0.pdf 规范