使用java检查器框架,为什么Map NonNull值不被接受到Map Nullable值位置?
通过此代码调用:
schema.validate(
MapMaker.makeMap(
new AbstractMap.SimpleEntry<>(
"foo",
"baz"
),
new AbstractMap.SimpleEntry<>(
"bar",
2
)
),
configuration
);
我收到此错误:
java: [argument] incompatible argument for parameter arg of validate.
found : @Initialized @NonNull Map<@Initialized @NonNull String, @Initialized @NonNull Object>
required: @Initialized @NonNull Map<@Initialized @NonNull String, @Initialized @Nullable Object>
验证方法定义为:
public FrozenMap<@Nullable Object> validate(Map<String, @Nullable Object> arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException {
任何非 null 对象都是可为 null 对象集合的子集,那么为什么这不起作用呢? 如何让它也适用于不可为空的键输入? 我是否需要为可为空和不可为空的输入参数使用不同的输入方法签名?
我传递给验证方法的参数将仅用于读取。根据检查器框架 javadocs,@Covariant 可能是这里的一个解决方案:
For example, consider Iterator. A client can read elements but not write them, so Iterator<@Nullable String> can be a subtype of Iterator<String> without introducing a hole in the type system. Therefore, its type parameter is annotated with @Covariant. The first type parameter of Map.Entry is also covariant. Another example would be the type parameter of a hypothetical class ImmutableList.
但这仅适用于接口。
之所以发生这种情况是因为检查器框架看到了
所以这里的解决方案是:
public FrozenMap<@Nullable Object> validate(Map<String, ? extends @Nullable Object> arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException {
Map<String, @Nullable Object> arg
Map<String, Object> arg
4 号示例代码如下所示
@Covariant(0)
public interface MapValidator <InType extends @Nullable Object, OutType> {
OutType validate(Map<String, InType> arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException;
}
public class SomeSchema implements MapValidator<@Nullable Object, FrozenMap<@Nullable Object>> {
OutType validate(Map<String, @Nullable Object> arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException {
...
}
}