我很抱歉将错误直接作为标题,但我找不到更好的标题。
我有一个定义如下的接口,用作我所有验证器类的蓝图:
public interface Validator<T> {
public boolean validate(T item);
}
然后我有一些可以实现它的类,让我们说其中一个是这样的:
public class EmptyStringValidator implements Validator<String> {
private final String _errorMessage;
public EmptyStringValidator() {
this("String cannot be empty.");
}
public EmptyStringValidator(String message) {
this._errorMessage = message;
}
@Override
public String getMessage() {
return this._errorMessage;
}
@Override
public boolean validate(String item) {
return gsi.application.core.Validation.isEmptyString(item);
}
}
我想把它全部放在一个数组中并在一个循环中调用它。所以这是我正在使用的代码:
public List<Validator<? extends Object>> validators;
public FormItem<T> addValidator(Validator<? extends Object> validator) {
this.validators.add(validator);
return this;
}
public boolean validate() {
for (Validator<? extends Object> validator : this.validators)
if (!validator.validate(this.getInputValue())) {
this._errorMessage = validator.getMessage();
return false;
}
return true;
}
但是,该代码在validate()
函数中给出了错误,特别是在此部分:
validator.validate(this.getInputValue())
它给了我提到的错误
The method validate(capture#2-of ? extends Object) in the type Validator<capture#2-of ? extends Object> is not applicable for the arguments (String)
这对我的理解没有意义。据我所知<? extends Object>
应该接受派生自Object类的任何内容,对吗?
有人能指出我做错了什么或者指出了我正确的方向吗? 感谢。
答案 0 :(得分:5)
另外,? extends Object
与?
没有什么不同。但是,这不是问题的根源。
问题是validators
是List<Validator<? extends Object>>
。换句话说,每个元素可以是任何种Validator<T>
,不一定是Validator<String>
。所以你可以放一个Validator<String>
,但当你拉出一个元素时你不知道它是什么类型的Validator
,所以你不知道它是否与该类型兼容由this.getInputValue()
返回。
最简单的解决方法是为type参数指定具体类型(例如:String
)。更复杂的修复方法是使用类型变量代替? extends Object
,并使getInputValue()
的类型签名使用相同的类型变量。您需要约束类型,以便getInputValue()
的返回类型可分配给validate()
的参数。
答案 1 :(得分:0)
对于收集的验证器来说,更好的类型通常是Validator<? super T>
,其中T
是输入类型,在这种情况下是String
。
这样addValidator(Validator<? super String> validator)
既接受Validator<String>
,也接受Validator<CharSequence>
和Validator<Object>
。
例如:
class LongerThan10 implements Validator<CharSequence> {
@Override
public boolean validate(CharSequence item) {
return item.length() > 10;
}
}
formItem.addValidator(str -> !str.isBlank())
formItem.addValidator(new LongerThan10());
在这种特定情况下,这没有多大意义,但是最好接受通常使用超类型的验证器。