我有一个更复杂的问题(比问题'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;
我知道我不能正确链接键和值(链接假设OK由于仅通过访问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()
;因此,在将注释投射到supportedAnnotationClass时,我应该能够将其作为参数传递给validate()
。为什么getSupportedAnnotationClass()
的结果与validate()
的参数被认为是不同的类型?
我可以通过删除验证程序声明和validate()
方法中的通配符来解决validate()
方法,但当然addValidator()
不会编译。
是的,编译器无法知道。这就是为什么我有一个强制连贯性的方法(addValidator())。现在我假设这种连贯性,我应该可以调用Class.cast(Object)。您的解决方案仍然需要投射物体,这是我想避免的。 – Gaetan 2009-02-05 13:47:04