【发布时间】:2014-11-15 05:53:12
【问题描述】:
我有一个泛型类,其中类型变量用于方法的参数。当我使用有界通配符从Set、Map 或List 检索泛型类的实例时,如何调用此方法?
泛型类的超类:
//Verifier.java
import java.lang.annotation.Annotation;
public interface Verifier<A extends Annotation> {
// A verifier needs the annotation to extract verification information.
public boolean verifyValue(Object value, A annotation);
}
具体实现:
//MinMaxVerifyer.java
public class MinMaxVerifyer implements Verifier<MinMax> {
@Override
public boolean verifyValue(Object value, MinMax annotation) {
if (!(value instanceof Number)) return false;
long l = ((Number)value).longValue();
long min = annotation.min();
long max = annotation.max();
return l >= min && l <= max;
}
}
示例中使用的注解:
//MinMax.java
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.METHOD)
@Inherited
public @interface MinMax {
long min() default Long.MIN_VALUE;
long max() default Long.MAX_VALUE;
}
包含违规调用的类:
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;
public class ParameterVerifier {
private static final Map<String, Verifier<? extends Annotation>> verifyers
= new HashMap<>();
static {
verifyers.put("MinMax", new MinMaxVerifyer());
// verifyers.put(Range.class, new RangeVerifier());
// verifyers.put(NotNull.class, new NotNullVerifier());
}
public void validate(Method method, Object value) {
for (Annotation annotation : method.getAnnotations()) {
String name = annotation.getClass().getSimpleName();
Verifier<? extends Annotation> verifier = verifyers.get(name);
if (verifier != null) {
boolean valid = verifier.verifyValue(value, annotation);
// ^ The method
// verifyValue(Object, capture#5-of ? extends Annotation)
// in the type Verifier<capture#5-of ? extends Annotation>
// is not applicable for the arguments (Object, Annotation)
}
}
}
}
我正在尝试让这个工作,以便用户可以添加他们自己的注释/验证器对,并且验证器应该使用注释子类进行参数化。我不在乎是否必须在ParameterVerifier 中进行一些转换(而不是在公共API 的验证器中)。我知道如何通过一些额外的逻辑来使添加对类型安全,为了清楚起见,这里省略了。
相关:The method validate(capture#2-of ? extends Object) in the type Validator<capture#2-of ? extends Object> is not applicable for the arguments (String) 和 Java generic/wildcard type mismatch 都建议限制为特定的 Verifier 子类型或从 Verifier 中删除类型变量。我正在寻找更优雅的解决方案。 (认为 MinMaxVerifyer.java 是不可变的,只适用于其他。)
【问题讨论】:
-
我不确定是否可以不将泛型参数移动到方法中。例如参见:
minmaxVerifier.varifyValue(null, somethingNotMinMax);这似乎是不合理的。 -
"我知道如何通过一些额外的逻辑使添加对类型安全,为了清楚起见,这里省略了。"
-
我看过那个评论,只是我怀疑它是可能的。你需要像
interface Verifier<A super Annotation>这样的东西,它不是有效的 Java 语法。 -
虽然在这种情况下我可以放宽
MinMaxVerifyer的要求,如果添加方法泛型参数可以解决问题。 -
当然,这就是为什么我提到将参数移动到方法(嗯,有错字),尽管它们与类泛型参数非常不同。可以尝试用不同的措辞来表达您到底想要实现什么?