我正在测试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中获得相同的结果?)
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)
但我认为这也很令人困惑,我会避免它。
| 归档时间: |
|
| 查看次数: |
548 次 |
| 最近记录: |