2012-11-26 117 views
19

注释可以有复杂的返回类型,比如HashMap。java注释可以像HashMap那样复杂的返回类型

我要寻找类似:

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface column { 
    public HashMap<String, String> table(); 
} 

,所以我可以有一个恒定的注解像(伪代码):

@column({table=(dbName, tableName), table=(dbName, tableName2)}) 
public static final String USER_ID = "userid"; 

如果注释不允许你有复杂的返回类型,那么这种情况下的任何良好做法?

+0

很好的问题.. –

回答

48

不,注释元素只能是基元类型,字符串,enum类型,Class,其他注释或其中任何一个的数组。代表这类结构的典型方法是声明另一个注解类型

public @interface TableMapping { 
    public String dbName(); 
    public String tableName(); 
} 

然后说

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface column { 
    public TableMapping[] table(); 
} 

,并使用注释作为

@column(table={ 
    @TableMapping(dbName="dbName", tableName="tableName"), 
    @TableMapping(dbName="db2", tableName="table2") 
}) 
public String userId = "userid"; 
+1

不要忘记枚举和类 –

+0

@AleksanderBlomskøld好点,谢谢。 –

+0

@IanRoberts我做了类似的事情,有点讨厌,如果只使用@表,即使某些列只有一个TableMapping必须有@表以及一个@ TableMapping。如果您对具有多个表映射的字段开始使用@ table,而对于只有一个表映射的列使用@ TableMapping。但后一种情况将有一个更复杂的方法来检索例如。 getColumnsInTableA()。 – Shengjie

3

几年后带来我们的Java 8.它提供了重复同一类的注释的方法。

在Java 8中,您可以声明一个注释以隐式包装在容器注释中。您声明为@Repeated(value=a_class)您想要重复的注释。当您添加可重复注释的多个实例时,编译器将自动将它们包装在指定为@Repeated的参数的容器注释a_class中。

如果声明:

@Retention(RetentionPolicy.RUNTIME) 
public @interface Columns { 
    Column[] value() default {}; 
} 

@Retention(RetentionPolicy.RUNTIME) 
@Repeatable(value = Columns.class) 
public @interface Column { 
    String dbName(); 
    String tableName(); 
} 

,那么你可以多次使用注释有或没有其他标注包装他们,都是等价的:

@Column(dbName="db1", tableName="table1") 
@Column(dbName="db2", tableName="table2") 
public static final String USER_ID = "userid"; 

@Columns({ 
     @Column(dbName="db3", tableName="table3"), 
     @Column(dbName="db4", tableName="table4") 
}) 
public static final String LAST_NAME = "last name"; 

的注解是在使用getAnnotationsByType(class)检索这两种情况。

public static void main(String[] args) { 
    for(Field field : AnnotationsTest.class.getDeclaredFields()){ 
     System.out.println("Field: " + field.getName()); 
     Column[] columns = field.getAnnotationsByType(Column.class); 
     for(Column column : columns){ 
      System.out.println(" db: " + column.dbName() + " table: " + column.tableName()); 
     } 
     System.out.println(); 
    } 
} 

它应该输出:

Field: USER_ID 
    db: db1 table: table1 
    db: db2 table: table2 

Field: LAST_NAME 
    db: db3 table: table3 
    db: db4 table: table4