У меня есть более сложная проблема (чем вопрос «Карта Java со значениями, ограниченными параметром типа ключа») для отображения ключа и типа значения в карте. Вот оно:
interface AnnotatedFieldValidator<A extends Annotation> {
void validate(Field f, A annotation, Object target);
Class<A> getSupportedAnnotationClass();
}
Теперь я хочу сохранить валидаторы на карте, чтобы я мог написать следующий метод:
validate(Object o) {
Field[] fields = getAllFields(o.getClass());
for (Field field: fields) {
for (Annotation a: field.getAnnotations()) {
AnnotatedFieldValidator validator = validators.get(a);
if (validator != null) {
validator.validate(field, a, target);
}
}
}
}
(параметры типа здесь опущены, поскольку у меня нет решения). Я также хочу иметь возможность зарегистрировать мои валидаторы:
public void addValidator(AnnotatedFieldValidator<? extends Annotation> v) {
validators.put(v.getSupportedAnnotatedClass(), v);
}
С помощью этого (только) открытого метода-модификатора я могу убедиться, что карта содержит записи, для которых ключ (класс аннотаций) соответствует поддерживаемому классу аннотаций валидатора.
Вот попытка:
Я объявляю карту валидаторов такой:
private Map<Class<? extends Annotation>, AnnotatedFieldValidator<? extends Annotation>> validators;
Я знаю, что не могу должным образом связать ключ и значение (связь считается нормальной из-за доступа только через addValidator()
), поэтому я попытался привести:
for (Annotation a: field.getAnnotations()) {
AnnotatedFieldValidator<? extends Annotation> validator = validators.get(a);
if (validator != null) {
validator.validate(field, validator.getSupportedAnnotationClass().cast(a), target);
}
}
Но это не работает: The method validate(Field, capture#8-of ?, Object) in the type AnnotatedFieldValidator<capture#8-of ?> is not applicable for the arguments (Field, capture#9-of ?, Object)
.
Я не могу понять, почему это не работает: AnnotatedFieldValidator
имеет параметр одного типа (A), который используется как тип возвращаемого значения getSupportedAnnotationClass()
и как параметр validate()
; таким образом, при приведении аннотации к supportAnnotationClass я должен иметь возможность передать его в качестве параметра validate()
. Почему результат getSupportedAnnotationClass()
считается типом, отличным от параметра validate()
?
Я могу решить метод validate()
, удалив символы подстановки в объявлении валидаторов и метод validate()
, но тогда, конечно, addValidator()
не скомпилируется.