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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13569079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 13:14:59  来源:igfitidea点击:

Can java annotation have complex return type like HashMap

javacollectionsannotations

提问by Shengjie

Can annotation have complex return type, such as HashMap.

注解可以有复杂的返回类型,比如HashMap。

I am looking for something like:

我正在寻找类似的东西:

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

so I can have a constant annotated like(pseudo code):

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

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

If Annotation doesn't allow you to have complex return type, then any good practice for this kind of case?

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

回答by Ian Roberts

No, annotation elements can only be primitive types, Strings, enumtypes, Class, other annotations, or arrays of any of these. The typical way to represent these kinds of structures would be to declare another annotation type

不可以,注释元素只能是原始类型、字符串、enum类型、Class、其他注释或其中任何一个的数组。表示这些类型结构的典型方法是声明另一种注释类型

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

then say

然后说

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

And use the annotation as

并使用注释作为

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

回答by Florian F

A couple of years later brings us Java 8. It offers a way to repeat annotations of the same class.

几年后,我们推出了 Java 8。它提供了一种重复同一类注释的方法。

In Java 8 you can declare an annotation to be implicitly wrapped in a container annotation. You declare as @Repeated(value=a_class)an annotation you want to be repeatable. When you add multiple instances of a repeatable annotation the compiler will automatically wrap these in the container annotation a_classspecified as argument to @Repeated.

在 Java 8 中,您可以声明一个注释隐式包装在容器注释中。您声明为@Repeated(value=a_class)一个注释,您希望它是可重复的。当您添加可重复注解的多个实例时,编译器会自动将这些实例包装在a_class指定为的容器注解中@Repeated

If you declare:

如果您声明:

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

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

then you can use the annotation multiple times with or without wrapping them in another annotation, both are equivalent:

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

@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";

The annotations are retrieved using getAnnotationsByType(class)in both cases.

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();
    }
}

It should output:

它应该输出:

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

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