【问题标题】:Can java annotation have complex return type like HashMapjava注解可以像HashMap这样复杂的返回类型吗
【发布时间】:2012-11-26 16:33:41
【问题描述】:

注解可以有复杂的返回类型,比如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";

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

【问题讨论】:

  • 很好的问题..

标签: java collections annotations


【解决方案1】:

不可以,注解元素只能是原始类型、字符串、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";

【讨论】:

  • 不要忘记枚举和类
  • @IanRoberts 我做过类似的事情,这有点烦人,如果你只使用@table,即使某些列只有一个TableMapping,也必须有@table 和一个@TableMapping。如果您开始对具有多个表映射的字段使用@table,而对只有一个表映射的列使用@TableMapping。但是后一种情况将具有更复杂的检索方法,例如。 getColumnsInTableA().
【解决方案2】:

几年后,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();
}

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

@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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    相关资源
    最近更新 更多