2013-03-01 12 views
6

Ich teste die neuen Schließfunktionen von Java 8; Ich frage mich, warum dieses Stück CodeJava 8 Verschlüsse und Typerkennung

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

den Fehler gibt: both method z(IFA) in Test8 and method z(IFB) in Test8 match error auf z Aufruf in der run-Methode

Ist das nicht der Compiler in der Lage zu erkennen, dass die forceA Aufruf Kräfte x vom Typ zu sein A und damit das richtige z zu verwenden ist z(IFA fun)?

(eine ähnliche Funktion ist legal in C# Delegaten, ist es eine Möglichkeit, um das gleiche Ergebnis in Java 8 zu bekommen?) Ist

+2

Wenn dies nicht kompiliert, dann ist der Compiler eindeutig nicht schlau genug, um das herauszufinden. –

Antwort

3

Java 8 ist noch in Arbeit. Die neueste Spezifikation ermöglicht es Ihrem Code zu arbeiten. Die Compiler-Implementierung sollte bald aufholen.

Dennoch ist diese Art der Überladung kein guter Stil. Wir haben Unterschriften

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

dann, wenn Javac

z(arg->{ block }) 

sieht es nicht ersichtlich, welche z() gilt. Zusätzliche Arbeit muss getan werden (indem Block kompiliert wird), um einen auszuwählen.

Wir kümmern uns nicht wirklich darum, wie schwierig es für javac ist. Das wirkliche Problem ist, wenn ein Mensch diesen Code sieht, muss der Mensch tiefer graben, um zu verstehen, auf welches z() Bezug genommen wird. Nicht gut lesbar.

Als Faustregel gilt, eine Methode mit funktionsgleichen Schnittstellen nicht zu überlasten. Verschiedene arities sind in Ordnung, es gibt kein Problem eindeutig zu machen, für die menschliche oder javac

z(arg->{...}) 

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

Eine andere Form der Überlastung auch von den Designern (Dan Smith usw.) gesegnet ist - gleiche arity, gleiche Parameter-Typen, aber unterschiedliche Rückgabetypen

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

aber ich denke, es ist auch ziemlich verwirrend und ich würde es vermeiden.

+0

Danke, ich werde versuchen, mit der neuen Version des Compilers, sobald es veröffentlicht wird. Ich weiß, dass es kein guter Stil ist, aber ich habe nur die Sprachfähigkeiten getestet. – Vor

0

Der Körper des Lambda nicht verwendet seinen Typ zu bestimmen. Wie Methoden. Ich denke, eine Methodenreferenz kann funktionieren. Aber euw, überladen.