Java 8 闭包和类型识别

标签 java closures

我正在测试 Java 8 的新闭包功能;我想知道为什么这段代码

public class Test8 {
    private class A { int a;}
    private class B { int b;}    
    interface IFA { void ifa(A param); }
    interface IFB { void ifb(B param); }
    private void forceA(A expr) {  }    
    private void z(IFA fun) { System.out.println( "A"); fun.ifa( new A() ); }
    private void z(IFB fun) { System.out.println( "B"); fun.ifb( new B() ); }    

    public void run() {
        z( x -> forceA(x) );
    }
    public static void main(String args[]) {   new Test8().run(); }
}

给出错误:test8 中的方法 z(IFA) 和 Test8 中的方法 z(IFB) 匹配错误在 run 方法中调用 z

编译器是否无法检测到 forceA 调用强制 x 为 A 类型,因此要使用的正确 z 是 z(IFA fun)

(类似的函数在 C# 中使用委托(delegate)是合法的;有没有办法在 Java 8 中获得相同的结果?)

最佳答案

Java 8 仍在进行中。最新规范确实允许您的代码工作。编译器的实现应该很快就会跟上。

不过,这种重载并不是一种好的风格。我们有签名

    z( A->void )
    z( B->void )

然后当javac看到

    z( arg->{ block } )

不清楚哪个 z() 适用。必须完成额外的工作(通过编译 block )来选择一个。

我们真的不关心javac有多难。真正的问题是,当人类看到该代码时,人类必须更深入地挖掘以理解引用了哪个 z()。可读性不强。

根据经验,避免重载具有相同数量的功能接口(interface)的方法。不同的arities很好,没有歧义,对于人类或javac来说都是没有问题的

    z( arg->{...} )

    z( (arg1,arg2)->{...} )

另一种形式的重载也受到设计者(Dan Smith 等)的青睐 - 相同的元数,相同的参数类型,但不同的返回类型

    z( X->R1 )
    z( X->R2 )

但我认为它也很困惑,我会避免它。

关于Java 8 闭包和类型识别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15168711/

相关文章:

java - hibernate 查询异常 : could not resolve property in spring petclinic sample application

java - 如何在 LibGDX 中左右移动相机

Javascript闭包继承: is it possible to have Functions with the same Name in the Base Object and the Derived One?

callback - Node.js 中的闭包有何不同?

java - 无法从根上下文 Autowiring 子 bean(在 Web 上下文中定义)

java - GWT 2.5.1 CellTable 和 SimplePager 问题

java - 下面这几行代码是什么意思

swift - 对闭包强引用循环感到困惑?

swift - 在 Swift 中,如何在已经使用一个的函数中使用完成处理程序?

reference - 为什么我不能从闭包中返回对外部变量的可变引用?