2013-03-01 8 views
6

Java 8の新しいクロージャ機能をテストしています。 runメソッドにおけるzの呼び出しにboth method z(IFA) in Test8 and method z(IFB) in Test8 match errorJava 8のクロージャとタイプの認識

forceA呼び出し力xは型であることを検出することができ、コンパイラではない:コード

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(); } 
} 

のこの作品は、エラーになりますなぜ私は思ったんだけどAと使用する正しいzはz(IFA fun)ですか?

(同様の機能は、デリゲートを使用してC#で合法であるジャワ8に同じ結果を得るための方法はありますか?)

+2

これがコンパイルされない場合、コンパイラは明らかにそれを理解するのに十分スマートではありません。 –

答えて

3

Java 8はまだ進行中です。最新の仕様では、コードを動作させることができます。コンパイラの実装はすぐに追いつくはずです。

しかし、この種のオーバーロードは良いスタイルではありません。私たちは、署名

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

のjavacが

z(arg->{ block }) 

を見たとき、それはz()が適用される見かけませんがあります。余分な作業は(ブロックをコンパイルすることによって)行わなければならない。

私たちは本当にjavacがいかに難しいか気にしません。実際の問題は、人間がそのコードを見ると、人間がより深く掘り下げて、z()が参照されていることを理解していることです。それほど読めない。

親指で、同じアリティの機能的インターフェイスでメソッドをオーバーロードしないようにします。異なるアリティは大丈夫です、明確にするために何ら問題はありません、ヒトまたはjavacの

z(arg->{...}) 

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

のためにオーバーロードの別の形態は、また、設計者(ダン・スミスなど)に恵まれている - 同じアリティ、同じパラメータ型が、異なる戻り値の型

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

でも、それはかなり混乱していると私はそれを避けると思います。

+0

ありがとう、私はコンパイラの新しいバージョンが公開されるとすぐにそれを試してみます。私はそれが良いスタイルではないことを知っていますが、私は言語(クロージャー)能力をテストしていました。 – Vor

0

ラムダの本体は、そのタイプを決定するために使用されていません。メソッドのように。私はメソッド参照が動作するかもしれないと思います。しかし、うーん、オーバーロード。

関連する問題