java注释可以像HashMap一样具有复杂的返回类型

She*_*jie 24 java collections annotations

注释可以具有复杂的返回类型,例如HashMap.

我正在寻找类似的东西:

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

所以我可以有一个常量注释(伪代码):

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

如果Annotation不允许你有复杂的返回类型,那么对于这种情况有什么好的做法吗?

Ian*_*rts 61

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

public @interface TableMapping {
  public String dbName();
  public String tableName();
}
Run Code Online (Sandbox Code Playgroud)

然后说

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

并使用注释作为

@column(table={
  @TableMapping(dbName="dbName", tableName="tableName"),
  @TableMapping(dbName="db2", tableName="table2")
})
public String userId = "userid";
Run Code Online (Sandbox Code Playgroud)


Flo*_*n F 9

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

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

如果你声明:

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

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

那么你可以多次使用注释,无论是否将它们包装在另一个注释中,两者都是等价的:

@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";
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

它应该输出:

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

Field: LAST_NAME
    db: db3 table: table3
    db: db4 table: table4
Run Code Online (Sandbox Code Playgroud)