Может ли аннотация 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";
Если аннотация не позволяет вам иметь сложный тип возврата, то любая хорошая практика для такого рода случаев?
Ответы
Ответ 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