【问题标题】:How the Lamba in static method instantiates the interface静态方法中的 Lambda 如何实例化接口
【发布时间】:2020-10-10 22:05:58
【问题描述】:

由于公司和个人的惰性,我已经做了一段时间的java,主要是java 1.7。 最近我决定开始学习更多关于 java 函数方面的知识,所以我开始使用 Function 接口并构建一个 Validator 来检查 Map 是否符合 Validator 标准。 这样验证器就可以像

一样以编程方式构建
Usage:

Map<String, String> book = new LinkedHashMap<String, String>();

book.put("Title", "Leviathan Wakes");
book.put("Subject", "A proto molecule");
book.put("Category", "sci-fi");
book.put("TotalPages", "350")

final ResourceValidator filter = ResourceValidator.containsProperty("Title").and(ResourceValidator.containsProperty("Category"));
assert filter.apply(book);

这是我生成的代码

    public interface ResourceValidator extends Function<Map<String,String>,Boolean> {
    
    static ResourceValidator containsProperty(String property) {
            return resource -> resource.containsKey(property);
        }

    default ResourceValidator and(ResourceValidator other){
        return resource -> this.apply(resource) && other.apply(resource);
    }
}

到目前为止,它的行为似乎符合预期,但我无法理解接口是如何实例化的。 呼吁

final ResourceValidator filter = ResourceValidator.containsProperty("Title");

调用接口的静态方法,ResourceValidator在静态方法中是如何以及在哪里实例化的?

static ResourceValidator containsProperty(String property) {
            return resource -> resource.containsKey(property);
        }

我一直在寻找,但我正在努力寻找答案

【问题讨论】:

  • 在计算 lambda 表达式 时,会创建一个 ResourceValidator 接口的实例作为结果。
  • @chrylis-cautiouslyoptimistic- 这就是我感到困惑的地方,我正在为这个概念而苦苦挣扎。接口没有构造函数,因为它们是接口,但正如您所说,当评估 lambda 表达式时,接口被创建。这只是我在 java 8 中必须接受的吗?
  • Interfaces 没有构造函数,但 objects 有,而且你一直使用它。 lambda 表达式创建实现该接口的一个对象(通过一些未指定的魔法手段)。
  • 在不声明类的情况下创建接口实现的实例,is possible since JDK 1.3。不同之处在于,lambda 表达式 1) 具有更简单和简洁的语法,2) 提供编译时类型安全性,以及 3) 在大多数情况下更有效。但它们只能实现功能接口,即只声明一个抽象方法的接口,该接口与 java.lang.Object (see also this) 的公共方法不匹配。

标签: java lambda java-8 functional-interface


【解决方案1】:

您提供了这些静态方法的实现。例如;当您创建一个 lambda 为 resource -&gt; resource.containsKey(property) 时,您实际上所做的是;

 return new ResourceValidator() {
            @Override
            public Boolean apply(Map<String, String> resource) {
                return resource.containsKey(property);
            }
        };

你实现了ResourceValidator函数的apply(是Function接口的子类型,标记为功能接口)。

所以现在你可以像这样调用它了;

ResourceValidator.containsProperty("foo").apply(Map.of("foo", "bar"));

您可能遇到过 Java lambda 表达式。不然这个还挺全面的https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

【讨论】:

  • 太棒了,谢谢,这很有意义,我的问题更荒谬。
  • 没问题,如果您使用 Intellij(不确定 Eclipse 等如何做),您可以四处玩耍并查看相同 lambda 实现的不同变体、方法引用等。只需按 Option/Alt + Enter 即可例如 lambda,称为意图动作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-26
  • 2012-09-23
  • 2012-03-13
  • 1970-01-01
  • 2012-03-14
  • 2017-08-21
相关资源
最近更新 更多