2014-05-15 3 views
7

ich dies tat:Lambda kann nur mit funktionaler Schnittstelle verwendet werden?

public class LambdaConflict 
{ 
    public static void main(String args[]){ 
     //* 
     System.out.println(LambdaConflict.get(
      (str) -> "Hello World!! By ME?" 
     )); 
     /*/ 
     System.out.println(LambdaConflict.get(new Intf<String>(){ 
      @Override public String get1(String str){ 
       return "Hello World!! By get1 " + str; 
      } 
     })); 
     /*****/ 
    } 

    public static String get(Intf<String> i, boolean b){ 
     return i.get1("from 1"); 
    } 
} 

interface Intf<T> 
{ 
    public T get1(T arg1); 

    public T get2(T arg1); 
} 

und diese Ausnahme erhalten:

inkompatible Typen: Intf ist keine funktionale Schnittstelle mehrere nicht-überwiegende abstrakte Methoden Intf Hinweis in der Schnittstelle gefunden: Einige Nachrichten haben wurde vereinfacht; neu kompiliert mit -Xdiags: ausführlicher volle Leistung 1 Fehler

Gibt es eine Bedingung zu erhalten, die ich nicht Lambda verwenden kann anonyme Klasse zu ersetzen?

+1

Was meinst du mit _overcome_ it? Verstehst du den Fehler? –

+0

1) Funktionsschnittstellen müssen nur 1 Methode haben. 2) sie müssen mit Anmerkungen versehen werden @FunctionalInterface –

+1

Funktionale Schnittstellen werden auch SAM-Typen (Single Abstract Method Types) genannt. Sie können also nur eine einzige abstrakte Methode in Ihrer funktionalen Schnittstelle haben. –

Antwort

15

Nein. Es gibt keine Möglichkeit, dies zu "überwinden". Eine funktionale Schnittstelle muss nur eine abstrakte Methode haben. Ihre Schnittstelle hat zwei:

interface Intf<T> { 
    public T get1(T arg1); 
    public T get2(T arg1); 
} 

Hinweis: Sie müssen nicht Ihre Schnittstelle mit Anmerkungen zu versehen, wie in den Kommentaren erwähnt. Sie können jedoch die @FunctionalInterface Annotation verwenden, um Fehler bei der Kompilierung zu erhalten, wenn Ihre Schnittstelle keine gültige funktionale Schnittstelle ist. So bringt es Ihnen ein bisschen mehr Sicherheit in Ihrem Code.

Für mehr siehe z.B. http://java.dzone.com/articles/introduction-functional-1

+1

Danke für den Tipp über '@ FunctionalInterface'! Ich vergesse, dass es besondere Eigenschaften hat. Außerdem habe ich festgestellt, dass die Aktualisierung auf den neuesten JDK8-Patch von Oracle auch hilft, Fehlermeldungen zu verbessern. Ältere Versionen von JDK8 erlauben manchmal Code oben zu kompilieren, scheitern jedoch mit einem 'java.lang.AbstractMethodError' zur Laufzeit. Neuere Versionen werden zur Kompilierzeit abgelehnt. – kevinarpe

1

Denk darüber nach:

  • Wie soll der Compiler wissen, ob Sie get1 oder get2 außer Kraft setzen wollen?

  • Wenn Sie nur get1 außer Kraft setzen, was wird get2 Implementierung? Auch der Code, den Sie auf Kommentar wird nicht funktionieren, weil Sie nicht get2 implementieren do ...

Es gibt Gründe für diese Einschränkung ...

0

Wie bereits erwähnt von @ Thomas-Uhrig, Funktionelle Grenzflächen kann nur eine Methode haben.

Ein Weg, dies zu beheben, vor allem, weil man nie public T get2(T arg1); verwendet, ist die Intf<T> Schnittstelle zu ändern:

@FunctionalInterface 
interface Intf<T> 
{ 
    public T get1(T arg1); 
} 
6

Gerade als Referenz und die Antworten schon gegeben zu bereichern:

Per JSR-335: Lambda Expressions for the Java Programming Language Im Abschnitt Lambda Specification, Teil A: Funktionsschnittstellen heißt es:

Eine funktionale Schnittstelle ist ein Interf Ass, das nur eine abstrakte Methode hat (abgesehen von den Methoden von Object), und stellt somit einen Einzelfunktionsvertrag dar. (In einigen Fällen kann diese "einzige" Methode die Form von mehreren abstrakten Methoden mit Override-Äquivalent Signaturen übernommen von Superschnittstellen annehmen, in diesem Fall repräsentieren die ererbten Methoden logisch eine einzige Methode.)

Sie müssen also entweder eine Standardimplementierung für eine Ihrer Methoden bereitstellen oder eine Ihrer Methoden in eine andere Schnittstelle einfügen.

Verwandte Themen