Supplier 接口中的 get() 在哪里实现?

Where is get() in Supplier interface implemented?

我有这段代码

public <T> someMethod(Supplier<T> supplier) {
        Objects.requireNonNull(supplier);
        SupplierThrowsException<T, Throwable> supplierThrowsException = supplier::get;
        return withThrowable(supplierThrowsException);
}

我是这样称呼它的

obj.someMethod(() -> myMethod(message))

我 100% 确定 myMethod() 返回的对象的 class 没有实现 Supplier 接口。那么get()的实现在哪里呢?

我浏览了 Javadoc,但什么也没得到。我想了解这里发生了什么。

我找到了 and ,但这并不能消除我的疑虑。如果我在这里遗漏任何内容,请告诉我。

我认为这份文件可能会阐明您的问题: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#target-typing

To determine the type of a lambda expression, the Java compiler uses the target type of the context or situation in which the lambda expression was found. It follows that you can only use lambda expressions in situations in which the Java compiler can determine a target type:

Variable declarations

Assignments

Return statements

Array initializers

Method or constructor arguments

Lambda expression bodies

Conditional expressions, ?:

Cast expressions

在这个调用中:

obj.someMethod(() -> myMethod(message))

您正在使用 lambda 表达式实现 Supplier 接口 - () -> myMethod(message).

就好像(我说 "as if" 因为这不是幕后实际发生的事情。Here 是幕后发生的事情)你已经创建了一个内部 class像这样实施 Supplier

static class MyInnerClass implements Supplier<SomeClass> {
    public SomeClass get() {
        return myMethod(message);
    }
}

然后将new MyInnerClass()传递给someMethod

I am 100% sure that the class of the object returned by myMethod() does not implement Supplier interface.

当然可以,但是表达式 () -> myMethod(message) 可以。

请阅读15.27.4. Run-Time Evaluation of Lambda Expressions

At run time, evaluation of a lambda expression is similar to evaluation of a class instance creation expression, insofar as normal completion produces a reference to an object. Evaluation of a lambda expression is distinct from execution of the lambda body.

Either a new instance of a class with the properties below is allocated and initialized, or an existing instance of a class with the properties below is referenced.

The value of a lambda expression is a reference to an instance of a class with the following properties:

  • The class implements the targeted functional interface type and, if the target type is an intersection type, every other interface type mentioned in the intersection.

简而言之,lambda 表达式 () -> myMethod(message) 将被解析为 Supplier 的实例。

Where is the implementation of get()?

您已在 lambda 正文中提供它。

() -> myMethod(message) 

(是语句表达式,是构造lambda体的一种较短形式)

() -> {
    return myMethod();
}

(这是一个值兼容的块,一个更扩展的版本,可以声明许多语句)

Supplier 是一个功能接口,包含以下单个抽象方法:

@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

现在,您已经通过以下调用提供了 definitionget 方法以及 instantiation

obj.someMethod(() -> myMethod(message))

上一行翻译如下:

obj.someMethod(new Supplier() {

@Override
public T get() 
{ 
  return myMethod(message);
}

});