lambda 的子类型检查错误
Subtype check error for lambda
我正在尝试为检查器框架实现一个简单的 subtyping check。
它基本上可以工作,但我收到一个我不明白的与 lambda 用法相关的错误。
我在 github 上创建了一个简单的测试项目:checkerfw-test 这样任何人都可以轻松重现该问题。
我使用的类型系统很像 docs/src 中的 RegEx
示例。
这是 link 到 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 returns 正是指定的类型。
测试源还包含一个函数 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
、...)
我正在使用检查器框架版本 2.2.0
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 类型推断。
我正在尝试为检查器框架实现一个简单的 subtyping check。
它基本上可以工作,但我收到一个我不明白的与 lambda 用法相关的错误。
我在 github 上创建了一个简单的测试项目:checkerfw-test 这样任何人都可以轻松重现该问题。
我使用的类型系统很像 docs/src 中的 RegEx
示例。
这是 link 到 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 returns 正是指定的类型。
测试源还包含一个函数 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
、...)
我正在使用检查器框架版本 2.2.0
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 类型推断。