Может ли аннотация java иметь сложный возвращаемый тип, такой как HashMap - программирование
Подтвердить что ты не робот

Может ли аннотация java иметь сложный возвращаемый тип, такой как HashMap

В аннотации может быть сложный возвращаемый тип, например 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";

Если аннотация не позволяет вам иметь сложный тип возврата, то любая хорошая практика для такого рода случаев?

4b9b3361

Ответ 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";

Ответ 2

Спустя пару лет мы приведем Java 8, в котором есть возможность написать несколько аннотаций одного и того же типа.

В Java 8 вы можете скрыть внешнюю аннотацию. Вы можете аннотировать @Repeated(value=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