我正在尝试为checker-framework实现一个简单的subtyping check 它基本上工作,但我得到一个与lambda-usage有关的错误,我不明白。
我在github上创建了一个简单的测试项目:checkerfw-test,这样任何人都可以轻松地重现这个问题。
我使用的类型系统与docs / src中的RegEx
示例非常相似。
这是my types的链接:
IdDomainObject
是顶级IdUser
,IdCustomer
是不应分配给彼此的自定义类型IdBottom
是底部类型我的 testFromCallable2() 功能的编译:
static class GenericHolder<T> {
public T field;
}
public static <T> GenericHolder<T> fromCallable(final Callable<? extends T> callable) {
GenericHolder<T> result = new GenericHolder<T>();
try {
result.field = callable.call();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public void testFromCallable2() {
GenericHolder<@IdCustomer Long> tmp2 = fromCallable(() -> {
final @IdCustomer Long customerId = toCustomerId(1);
return customerId;
}
);
}
使用此错误消息失败:
GenericHolder<@IdCustomer Long> tmp2 = fromCallable(() -> {
required: @IdDomainObject GenericHolder<@IdCustomer Long>
我不认为这会失败,因为lambda会返回指定的类型。
测试源还包含一个函数testFromCallable1,它也是一样的,只是没有lambda,这个代码可以工作:
public void testFromCallable1() {
GenericHolder<@IdCustomer Long> tmp = fromCallable(new Callable<@IdCustomer Long>() {
@Override
public @IdCustomer Long call() throws Exception {
final @IdCustomer Long customerId = toCustomerId(1);
return customerId;
}
});
}
我错过了什么?
注意:
我刚刚开始使用子类型检查器,所以我想我还没有理解所有关于子类型的文档:例如也许我只是为我的类型定义上的一些注释设置了一些错误的值(例如@ImplicitFor
,@DefaultFor
,...)
我使用的是checker-framework版本2.2.0
答案 0 :(得分:1)
Checker Framework尚未完全实现Java 8类型推断。见Issue #979。您可以通过明确指定fromCallable
的类型参数来解决此限制。
GenericHolder<@IdCustomer Long> tmp2 = this.<@IdCustomer Long>fromCallable(() -> {
final @IdCustomer Long customerId = toCustomerId(1);
return customerId;
}
);
testFromCallable1
没有发出错误,因为它没有使用Java 8类型推断。