Reputation: 448
I created a simple annotation class:
@Retention(RUNTIME)
public @interface Column {
public String name();
}
I use it in some classes like this:
public class FgnPzt extends Point {
public static final String COLUMN_TYPE = "type";
@Column(name=COLUMN_TYPE)
protected String type;
}
I know that I can iterate over the declared fields and obtain the annotation like this:
for (Field field : current.getDeclaredFields()) {
try {
Column c = field.getAnnotation(Column.class);
[...]
} catch(Exception e) {
[...]
}
}
How can I obtain the field type
directly by its annotated name without iterating over declared fields of the class?
Upvotes: 2
Views: 5470
Reputation: 25980
If you need to make multiple accesses you can pre-process the annotations.
public class ColumnExtracter<T> {
private final Map<String, Field> fieldsByColumn;
public ColumnExtracter(Class<T> clazz) {
this.fieldsByColumn = Stream.of(clazz.getDeclaredFields())
.filter(field -> field.isAnnotationPresent(Column.class))
.collect(Collectors.toMap(field -> field.getAnnotation(Column.class).name(), Function.identity()));
}
public Field getColumnField(String columnName) {
return fieldsByColumn.get(columnName);
}
public <R> R extract(String columnName, T t, Class<R> clazz) throws IllegalAccessException {
return clazz.cast(extract(columnName, t));
}
public Object extract(String columnName, T t) throws IllegalAccessException {
return getColumnField(columnName).get(t);
}
}
Upvotes: 6