简体   繁体   English

供应商接口中的get()在哪里实现?

[英]Where is get() in Supplier interface implemented?

I have this piece of code 我有这段代码

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

I am calling it like this 我这样称呼它

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

I am 100% sure that the class of the object returned by myMethod() does not implement Supplier interface. 我100%确定myMethod()返回的对象的类未实现Supplier接口。 So where is the implementation of get() . 那么get()的实现在哪里。

I went through the Javadoc, I didn't get anything. 我通过了Javadoc,但一无所获。 I would like to understand what's going on here. 我想了解这里发生了什么。

I found this and this but it doesn't clear my doubt. 我发现这个这个 ,但它并不清楚我的疑问。 Let me know if I am missing anything here. 让我知道我是否在这里想念任何东西。

In this call: 在此通话中:

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

you are implementing the Supplier interface using a lambda expression - () -> myMethod(message) . 您正在使用lambda表达式- () -> myMethod(message)来实现Supplier接口。

It is as if (I say "as if" because this is not what actually happens under the hood. Here is what happens under the hood) you have created an inner class implementing Supplier like this: 就好像您创建了一个内部类来实现Supplier的内部类一样(我说“好像”,因为这不是实际发生在幕后。 是实际发生在幕后):

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

And then passed new MyInnerClass() to someMethod . 然后将new MyInnerClass()传递给someMethod

I am 100% sure that the class of the object returned by myMethod() does not implement Supplier interface. 我100%确定myMethod()返回的对象的类未实现Supplier接口。

Sure, but the expression () -> myMethod(message) does. 可以,但是表达式() -> myMethod(message)可以。

Please, read 15.27.4. 请阅读15.27.4。 Run-Time Evaluation of Lambda Expressions . Lambda表达式的运行时评估

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. 在运行时,只要正常完成生成对对象的引用,对lambda表达式的求值就类似于对类实例创建表达式的求值。 Evaluation of a lambda expression is distinct from execution of the lambda body. Lambda表达式的计算与Lambda主体的执行不同。

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: lambda表达式的值是对具有以下属性的类的实例的引用

  • 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. 该类实现目标功能接口类型 ,如果目标类型是路口类型,则实现路口中提到的所有其他接口类型。

In short, the lambda expression () -> myMethod(message) will be resolved to an instance of Supplier . 简而言之,lambda表达式() -> myMethod(message)将解析为Supplier的实例。

Where is the implementation of get ()? get ()的实现在哪里?

You've provided it within the lambda body. 您已在lambda主体中提供了它。

() -> myMethod(message) 

(it's a statement expression, a shorter form to construct a lambda body) (这是一个语句表达式,是构造lambda主体的较短形式)

() -> {
    return myMethod();
}

(it's a value-compatible block, a more expanded version where many statements may be declared) (这是一个值兼容的块,是一个更扩展的版本,可以在其中声明许多语句)

I think this document may shed some light on your question: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#target-typing 我认为该文档可能会阐明您的问题: 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. 为了确定lambda表达式的类型,Java编译器使用找到lambda表达式的上下文或情况的目标类型。 It follows that you can only use lambda expressions in situations in which the Java compiler can determine a target type: 因此,您只能在Java编译器可以确定目标类型的情况下使用lambda表达式:

Variable declarations 变量声明

Assignments 作业

Return statements 退货声明

Array initializers 数组初始化器

Method or constructor arguments 方法或构造函数参数

Lambda expression bodies Lambda表达体

Conditional expressions, ?: 条件表达式,?:

Cast expressions 转换表达式

Supplier is a functional interface and contains following single abstract method: Supplier是一个功能接口,包含以下单个抽象方法:

@FunctionalInterface
public interface Supplier<T> {

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

Now, you have provided definition of get method along with instantiation with following invocation: 现在,您通过以下调用提供了get方法的definition以及instantiation

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

Above line gets translated as follows: 上面的行翻译如下:

obj.someMethod(new Supplier() {

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

});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM