lambda的子类型检查错误

时间:2017-09-18 16:02:47

标签: java checker-framework

我正在尝试为checker-framework实现一个简单的subtyping check 它基本上工作,但我得到一个与lambda-usage有关的错误,我不明白。

我在github上创建了一个简单的测试项目:checkerfw-test,这样任何人都可以轻松地重现这个问题。

我使用的类型系统与docs / src中的RegEx示例非常相似。
这是my types的链接:

  • IdDomainObject是顶级
  • IdUserIdCustomer是不应分配给彼此的自定义类型
  • 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

1 个答案:

答案 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类型推断。