当前位置: 首页 > 知识库问答 >
问题:

与通用供应商和lambda进行类型检查

姚培
2023-03-14
private <T> void compareValues(Supplier<T> supplier, T value) {
    System.out.println(supplier.get() == value);
}

private <T> void setValue(Consumer<T> consumer, T value) {
    consumer.accept(value);
}
compareValues(this::getString, "Foo"); // Valid, as expected
compareValues(this::getInt, "Foo");    // Valid, but compiler should raise error
compareValues(this::getString, 1);     // Valid, but compiler should raise error

setValue(this::setString, "Foo");      // Valid, as expected
setValue(this::setInt, "Foo");         // Type mismatch, as expected
setValue(this::setString, 1);          // Type mismatch, as expected


private String getString() {
    return  "Foo";
}

private int getInt() {
    return 1;
}

private void setString(String string) {
}

private void setInt(int integer) {
}

怎么会呢?编译器只是太笨拙,无法在这里正确地推理类型,还是这是类型系统的一个特性?如果有,导致这种行为的规则是什么?此外,如果可能的话,我如何创建compareValues的“类型安全”版本而不添加人工参数?

请注意,所提供的方法仅仅包含一个虚拟实现,并不反映我的实际代码库中的代码。这里的重点仅仅是方法调用。

共有1个答案

齐琦
2023-03-14

其他人已经提到了为什么会发生这种情况,所以这里有一个解决方案来绕过这个问题。

如果您创建一个泛型类,将供应商的传递与参数的传递分开,那么您就没有给编译器选择交集类型的机会:

public class Comparer<T>
{
    private final Supplier<T> supplier;

    Comparer(final Supplier<T> supplier)
    {
        this.supplier = supplier;
    }

    void compare(T value)
    {
        System.out.println(supplier.get() == value);
    }
}

new Comparer<>(this::getString).compare("Foo"); // Valid, as expected
new Comparer<>(this::getInt).compare("Foo"); // Invalid, compiler error
new Comparer<>(this::getString).compare(1);  // Invalid, compiler error

通过分离这种行为,您还允许comparer做一些可能有用的事情,比如缓存supplier.get()的结果。

 类似资料:
  • 我有疑问。我写了一个流类型检查器来检查我的减速器。有一个错误,你能给我解释一下错误的原因吗。这是我的密码。 这是错误。 错误------------------------------------------------------------------------------------------------------------------------------------------

  • 问题内容: 我正在尝试使用此Golang Yelp API软件包。在某些结构中,它使用guregu的null包中定义的类型。 我想声明一个在Yelp API包中定义的结构,其中的某些字段作为值使用(即,该结构,我正在尝试使用)。因此,在我的程序中,我同时导入了Yelp API包和guregu的null包,并尝试使用ip.Lat和ip.Lat为float64s声明该结构。(定义): 但是当我运行该程

  • 查询供应商列表 接口描述 获取所有供应商列表 URL /provider HTTP Method GET 请求参数 无 返回参数 返回参数 是否必须 类型 描述 providerId true String 供应商编号 providerName true String 供应商名称 HTTP请求示例 GET /provider HTTP/1.1 Host: api.miot.10046

  • 问题内容: 我如何在Supplier这里用lambda表达式替换代码 上面这段代码的输出是: 问题答案: 如果您必须专门使用以下内容: 编辑:使用IntStream.generate,您可以将其执行为 注意:就API设计而言,更好的解决方案肯定是利用这种用例。

  • 寻找如何使用Javalambda函数,以便消费者可以处理供应商提供的所有对象,并在循环和检查时摆脱显式