使用注解功能时,如果需要用反射读取注解,就必须设置@Retention(RetentionPolicy.RUNTIME),因为默认情况下为CLASS,读取的时候会报异常
@Retention可选参数:RetentionPolicy
编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。 |
编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。 |
编译器要丢弃的注释。 |
@Target可以限制注解针对的对象:
|
|
|
|
|
|
|
类、接口(包括注释类型)或枚举声明 |
上面两个注解在我们写注解的时候常用的,如果需要查看注解的详细说明,请看这里:
http://www.blogjava.net/mlh123caoer/archive/2007/09/06/143260.html
下面是我写的一个简单例子,通过注解,自动生成创建表的SQL
先是两个注解:@SqlTable和@SqlColumn
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SqlTable {
public String name();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SqlColumn {
//列名
public String name() default "";
//长度
public int length() default 0;
//是否允许空
public boolean notNull() default false;
//类型通过反射获取
}
一个用来测试的简单类:TableTest
@SqlTable(name="tableTest")
public class TableTest {
@SqlColumn(name="username",length=20,notNull=true)
private String name;
@SqlColumn(name="age")
private Integer ageInteger;
@SqlColumn()
private Date birthday;
@SqlColumn(name="bz",length=200,notNull=false)
private String beizhu;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAgeInteger() {
return ageInteger;
}
public void setAgeInteger(Integer ageInteger) {
this.ageInteger = ageInteger;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
处理注解的方法:
public class SqlCreateTable {
@SuppressWarnings("rawtypes")
public static String CreateTableSql(Object obj) throws Exception{
String tablename = null;
//通过isAnnotationPresent判断是否存在注解
if(obj.getClass().isAnnotationPresent(SqlTable.class)){
//获取类的注解
SqlTable sqlTable = obj.getClass().getAnnotation(SqlTable.class);
//获取注解参数值
tablename = sqlTable.name();
}
else {
tablename = obj.getClass().getName();
}
//获取全部字段
Field[] fields = obj.getClass().getDeclaredFields();
StringBuffer createTable = new StringBuffer("create table ").append(tablename).append("(\n");
StringBuffer fieldBuffer = new StringBuffer();
for(Field field:fields){
//获取注解
if(field.isAnnotationPresent(SqlColumn.class)){
SqlColumn sqlColumn = field.getAnnotation(SqlColumn.class);
String name = sqlColumn.name();
if(name.equals("")){
name = field.getName();
}
String type = null;
String Null = "";
boolean notNull = sqlColumn.notNull();
if(notNull){
Null = "not null";
}
Integer length = sqlColumn.length();
Class fieldType = field.getType();
if(fieldType==String.class){
type = "varchar2";
if(length==0){
length = 50;
}
}
else if(fieldType == Integer.class){
type = "number";
if(length==0){
length = 12;
}
}
else if(fieldType == Date.class){
type = "date";
}
else {
throw new Exception("字段类型错误!");
}
//合并字符串
StringBuffer columnBuffer = new StringBuffer("\t");
columnBuffer.append(name).append(" ").append(type);
if(type.equals("date")){
columnBuffer.append(Null);
}else {
columnBuffer.append("(").append(length).append(")").append(" ").append(Null);
}
if(!fieldBuffer.toString().equals("")){
fieldBuffer.append(",\n");
}
//加入到字段列表
fieldBuffer.append(columnBuffer.toString());
}
}
createTable.append(fieldBuffer.toString()).append("\n)");
return createTable.toString();
}
/**
* 测试
* @param args
*/
public static void main(String[] args) {
TableTest tableTest = new TableTest();
try {
String sql = SqlCreateTable.CreateTableSql(tableTest);
System.out.println(sql);
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出结果:
create table tableTest(
username varchar2(20) not null,
age number(12) ,
birthday date,
bz varchar2(200)
)