【问题标题】:Why can a method reference be inserted in a list of interfaces in Java?为什么方法引用可以插入到 Java 的接口列表中?
【发布时间】:2019-11-09 12:50:23
【问题描述】:

我不明白为什么这段代码编译时没有错误或警告:

import java.util.ArrayList;
import java.util.List;

class A {}

interface I {
    void methodI();
}

public class B {
    public void test() {
        List<I> l = new ArrayList<>();
        l.add(A::new);
    }
}

毕竟,A::new 应该是一个 lambda(如我打印 l.get(0) 时给出的B$$Lambda$/1/... 所示),所以我不明白为什么它可以放入 I 接口列表中。 (我使用的是 Java 8,但也是tested with Java 10)

【问题讨论】:

    标签: java lambda interface


    【解决方案1】:

    这正是使用 lambda 和方法引用的方式:通过将它们分配给 functional interface,一个具有单个抽象方法的接口。否则它们不会编译。

    如果您要检查B$$Lambda$/1/...,您会发现implements I 是一个自动生成的类。

    这些sn-ps都是等价的:

    l.add(A::new);
    
    l.add(() -> new A());
    
    l.add(() -> { new A(); });
    
    l.add(new I() {
        @Override public void methodI() {
            new A();
        }
    });
    

    (请注意,这不是一个有用方法。它会创建一个新对象并立即将其丢弃。A::new 是void methodI() 的有效匹配项,但它很可能是语义错误。如果接口是A methodI()或Object methodI()之类的就更好了。)

    【讨论】:

    • 请注意,这是初学者的错误,他们想做 l.add(new SomeObject());但改为 l.add(SomeObject::new);因为失误。然而,由于他们的界面只有一种方法(偶然),它编译并且他们的程序不起作用。感谢您的详细回答,我不知道任何一种方法的接口是功能接口。
    猜你喜欢
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-31
    • 2011-10-19
    • 2016-07-12
    • 2012-11-23
    • 2020-12-23
    相关资源
    最近更新 更多