【问题标题】:Why is this allowed? Implicit conversion from lambda acting as the missing method of an interface to the interface为什么允许这样做?从作为接口缺失方法的 lambda 到接口的隐式转换
【发布时间】:2016-02-11 16:02:50
【问题描述】:

背景:我是 Java 新手(具有 C++ 背景)。

那么,假设我有一个实现Iterator 接口的类:

public class C implements Iterator<concreteType>{
    // implementation
}

那么由于Iterable&lt;T&gt; 是一个只需要定义Iterator&lt;T&gt; iterator(); 方法的接口,因此允许以下内容(参见底部的编辑以获取最小示例):

Iterable<concreteType> coll = () -> new C<concreteType>();

我对“赋值运算符”周围发生的事情感到很困惑。

我右边的是一个(使用 C++ 语言)函数对象。并且将函数对象分配给Iterable 似乎没有意义。 Java中不是禁止运算符重载吗?

第二种可能性是运行 lambda,返回一个 C,然后又分配给 Iterable。是在此处进行隐式类型转换(CIterable)还是从 lambda 返回的类型C 变量临时构造的Iterable,然后将临时分配给coll? [这似乎不是这种情况,因为如果实际调用了 ctor,则运行时不会按要求打印底部的示例。]

第三种可能性是 lambda 提供了实现 Iterable 接口所必需且足够的缺失方法,临时 Iterable 由 lambda 简单地构造,然后分配给左侧。在这种情况下,是否真的有一个临时正在构建(所以后来被回收)或者没有涉及临时但类型转换(lambda 到 Iterable)是自动完成的?

谢谢。

编辑#:

在解决否决票时,这是一个可编译的最小示例:

import java.util.Iterator;

public class C implements Iterator<Integer>{

    private Integer nextInt;
    private Integer i;

    public C() // to test if the constructor is actually called
    {
        System.out.println("C ctor");
    }

    public boolean hasNext()
    {
        return nextInt != null;
    }

    public Integer next()
    {
       return nextInt;
    }

    public static void main(String [] args)
    {
        Iterable<Integer> coll = () -> new C();
    }
}

【问题讨论】:

    标签: java lambda type-conversion


    【解决方案1】:

    是的,这是允许的。 (这不是特别好的做法,因为 Iterable 没有注释 @FunctionalInterface,这意味着它不打算以这种方式使用。)

    将函数对象分配给 Iterable 似乎没有意义。

    为什么? Iterable 实际上是迭代器的供应商。你得到的就相当于

    new Iterable<ConcreteType>() {
      @Override public Iterator<ConcreteType> iterator() {
        return new C<ConcreteType>();
      }
    }
    

    我很难弄清楚你在说什么,但实际发生的事情似乎最接近你提到的第三种可能性。您正在创建一个新的 Iterable,当要求提供迭代器时,它会创建一个 new C&lt;ConcreteType&gt;() 并返回它。

    【讨论】:

    • “将函数对象分配给可迭代对象对我来说没有意义”的原因是这两种类型实际上是针对不同的事物:一种是提供对某些事物的访问,另一种是提供一个动作。甚至认为“行动”原则上可以是“提供访问权限”,这真的很奇怪。
    猜你喜欢
    • 2016-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-17
    • 2017-02-24
    • 2018-02-05
    • 2011-08-22
    • 1970-01-01
    相关资源
    最近更新 更多