方法参考 - 使用Consumer参数将Function传递给方法 [英] Method Reference - passing Function to method with Consumer argument

查看:713
本文介绍了方法参考 - 使用Consumer参数将Function传递给方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Java 8中的方法参考,我很难理解为什么会这样做?

I'm learning about Method References from Java 8 and I have difficulties understanding why does this work?

class Holder {
    private String holded;

    public Holder(String holded) {
        this.holded = holded;
    }

    public String getHolded() {
        return holded;
    }
}

private void run() {
    Function<Holder, String> getHolded = Holder::getHolded;

    consume(Holder::getHolded); //This is correct...
    consume(getHolded);         //...but this is not
}

private void consume(Consumer<Holder> consumer) {
    consumer.accept(null);
}

正如您在中看到的那样运行方法 - Holder :: getHolded 返回未绑定的方法引用,您可以通过传递 Holder 类型的对象来调用一个论点。像这样: getHolded.apply(holder)

As you can see in run method - Holder::getHolded returns unbound method reference which you can invoke by passing object of type Holder as an argument. Like this: getHolded.apply(holder)

但是为什么它将这个未绑定的方法引用转换为 Consumer 当它直接作为方法参数调用时,当我明确地传递 Function 时它没有这样做?

But why it casts this unbound method reference to Consumer when it is invoked directly as an method argument, and it does not doing it when I'm passing Function explicitly?

推荐答案

这里有两件事,lambda表达式是多元表达式 - 编译器使用它们的上下文推断(比如例如泛型。

Two things here, lambda expressions are poly expressions - they are inferred by the compiler using their context (like generics for example).

当你声明消耗(Holder :: getHolded); 时,编译器(在此之下) - 所谓特殊无效兼容性规则)会将其推断为消费者<持有人>

When you declare consume(Holder::getHolded);, compiler (under the so-called special void compatibility rule) will infer it to Consumer<Holder>.

这看起来可能并不明显,但想想一个简化的例子。调用一个方法并丢弃它的返回类型通常不仅仅是好的,对吧?例如:

And this might not look obvious, but think of a simplified example. It is generally more than ok do call a method and discard it's return type, right? For example:

List<Integer> list = new ArrayList<>();
list.add(1);

即使 list.add(1)返回一个布尔值,我们不关心它。

Even if list.add(1) returns a boolean, we don't care about it.

因此,你的例子可以简化为:

Thus your example that works can be simplified to:

consume(x -> {
        x.getHolded(); // ignore the result here
        return;
});

所以这些都是可能的和有效的声明:

So these are both possible and valid declarations:

Consumer<Holder> consumer = Holder::getHolded;
Function<Holder, String> function = Holder::getHolded;

但是在这种情况下,我们明确地告诉什么类型是 Holder :: getHolded ,这不是编译器推断,因此消耗(getHolded); 失败,消费者!= 功能毕竟。

But in this case we are explicitly telling what type is Holder::getHolded,, it's not the compiler inferring, thus consume(getHolded); fails, a Consumer != Function after all.

这篇关于方法参考 - 使用Consumer参数将Function传递给方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆