前段时间,Oracle 决定在 Java 8 中添加闭包是一个好主意。我想知道与 Scala 相比,那里的设计问题是如何解决的,Scala 从第一天开始就关闭了。
引用javac.info的未解决问题:
方法句柄可以用于函数类型吗? 如何使其工作尚不清楚。一个问题是方法句柄具体化了类型参数,但是以一种干扰函数子类型的方式。
我们可以摆脱“抛出”类型参数的显式声明吗? 这个想法是在声明的绑定是检查异常类型时使用析取类型推断。这不是严格向后兼容的,但不太可能破坏真实的现有代码。然而,由于句法歧义,我们可能无法摆脱类型参数中的“抛出”。
禁止在旧式循环索引变量上使用 @Shared
处理像 Comparator 这样定义多个方法的接口,除了其中一个方法之外,所有这些接口都将由继承自 Object 的方法实现。“单一方法的接口”的定义应该只计算不会由 Object 中的方法实现的方法,并且如果实现其中一个方法将实现所有方法,则应该将多个方法计算为一个。主要是,这需要更精确地说明接口只有一个抽象方法意味着什么。
指定函数类型到接口的映射:名称、参数等。我们应该完全指定函数类型到系统生成的接口的映射。
类型推断。需要扩充类型推断的规则以适应异常类型参数的推断。同样,闭包转换使用的子类型关系也应该体现出来。
删除异常类型参数以帮助改进异常透明度。 也许使省略的异常类型参数意味着界限。这可以通过添加新的泛型异常参数来改造没有异常类型参数的现有泛型接口,例如 java.util.concurrent.Callable。
函数类型的类文字是如何形成的? 是 #void().class 吗?如果是这样,如果对象类型被擦除,它是如何工作的?是 #?(?).class 吗?
系统类加载器应该动态生成函数类型接口。 与函数类型对应的接口应该由引导类加载器按需生成,以便在所有用户代码之间共享。对于原型,我们可能让 javac 生成这些接口,以便原型生成的代码可以在库存 (JDK5-6) 虚拟机上运行。
lambda 表达式的求值必须每次都产生一个新对象吗? 希望不会。例如,如果 lambda 没有从封闭范围捕获变量,则可以静态分配它。同样,在其他情况下,如果 lambda 未捕获循环内声明的任何变量,则可以将其移出内部循环。因此,如果规范对 lambda 表达式结果的引用身份不承诺任何内容,那将是最好的,这样编译器就可以完成这种优化。
据我了解 2.、6. 和 7. 在 Scala 中不是问题,因为 Scala 不使用 Checked Exceptions 作为某种“影子类型系统”,如 Java。
其余的呢?