Java 8闭包和类型识别

Vor*_*Vor 6 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(); }
}
Run Code Online (Sandbox Code Playgroud)

给出错误: both method z(IFA) in Test8 and method z(IFB) in Test8 match error在run方法中的z调用

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

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

irr*_*ble 3

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

尽管如此,这种重载并不是一个好的风格。我们有签名

    z( A->void )
    z( B->void )
Run Code Online (Sandbox Code Playgroud)

然后当 javac 看到

    z( arg->{ block } )
Run Code Online (Sandbox Code Playgroud)

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

我们并不真正关心 javac 有多困难。真正的问题是,当人们看到该代码时,人们必须更深入地挖掘才能理解所z()引用的内容。可读性不太好。

根据经验,避免使用相同数量的功能接口重载方法。不同的参数没问题,对于人类或 javac 来说没有消除歧义的问题

    z( arg->{...} )

    z( (arg1,arg2)->{...} )
Run Code Online (Sandbox Code Playgroud)

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

    z( X->R1 )
    z( X->R2 )
Run Code Online (Sandbox Code Playgroud)

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