我正在测试Java8的新闭包特性;我想知道为什么这段代码
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方法中给出错误:both method z(IFA) in Test8 and method z(IFB) in Test8 match error on z调用
难道编译器不能检测到forceA调用强制x为A类型,因此正确使用的z是z(IFA fun)吗?
(在使用委托的C#中,类似的函数是合法的;在Java8中有没有办法获得相同的结果?)
发布于 2013-03-02 09:16:16
Java 8仍在开发中。最新的规范确实允许您的代码工作。编译器的实现应该很快就会跟上。
然而,这种重载并不是一种好的风格。我们有签名
z( A->void )
z( B->void )然后,当javac看到
z( arg->{ block } )目前还不清楚哪种z()适用。必须做额外的工作(通过编译代码块)来选择一个。
我们并不关心javac有多难。真正的问题是,当人们看到这些代码时,他们必须更深入地挖掘,才能理解引用的是哪个z()。可读性不是很好。
根据经验,避免重载具有相同大小的函数接口的方法。对于人类或爪哇来说,不同的特性都很好,没有问题去消除歧义。
z( arg->{...} )
z( (arg1,arg2)->{...} )另一种形式的重载也得到了设计者(Dan Smith等)的青睐-相同的参数类型,但不同的返回类型
z( X->R1 )
z( X->R2 )但我认为它也是相当令人困惑的,我会避免它。
发布于 2013-03-02 09:06:22
lambda的主体不用于确定其类型。类似的方法。我猜方法引用可能会起作用。但是,真的超载了。
https://stackoverflow.com/questions/15168711
复制相似问题