2016-09-26 6 views
3

Ich habe zu schreiben, die zwei Methoden wie folgt:wie Lambda-Ausdruck für die abstrakte Klasse abstrakte Klasse

public abstract class SessionExecutionBody { 
    public Object execute() { 
    executeWithoutResult(); 
    return null; 
    } 

    public void executeWithoutResult() {} 
} 

und ich die Klasse wie folgt implementieren:

final HTTPDestination destination = sessionService.executeInLocalView(new SessionExecutionBody() { 
      @Override 
      public Object execute() { 
       userService.setCurrentUser(userService.getAdminUser()); 
       final String destinationName = getConfigurationService().getConfiguration().getString(DESTINATION_PROPERTY); 
       return getHttpDestinationService().getHTTPDestination(destinationName); 
Als ich sonarLint seinen Lauf zeigen große Ausgabe konvertieren diese anonyme Klasse zu Lambda-Ausdruck, aber ich bin nicht in der Lage, den Weg zu Recht das gleiche zu finden, kann ich diesen Ausdruck in ein Lambda konvertieren?

+3

verwenden können, können Sie nicht Machen Sie einen Lambda-Ausdruck aus einer abstrakten Klasse. Lambdas können nur aus funktionalen Schnittstellen erstellt werden. – Jhonny007

Antwort

6

Ich fürchte, Sie können nicht. Das ist keine funktionale Schnittstelle mit einer abstrakten Methode, um es im Lambda-Stil zu implementieren.

Kann ich diesen Ausdruck in ein Lambda umwandeln?

Sie könnten, wenn Sie folgende Änderungen vornehmen:

@FunctionalInterface // to guarantee the next rule 
interface SessionExecutionBody { 
    Object execute(); // has exactly one abstract method 

    default void executeWithoutResult() {} // other methods should be default/static 
} 
... 
sessionService.executeInLocalView(() -> { /* a body */ return ...; }) 
2

Sie können die Unterklasse eines abstract class in einen Lambda-Ausdruck konvertieren und ein Audit-Tool anders sagen, kann in Betracht gezogen werden, um einen Fehler zu haben. Als Andrew Tobilko showed würde eine Lösung zur Verwendung eines Lambda-Ausdrucks hier die abstract class in eine interface umwandeln.

Wenn das keine Option ist, z.B. aufgrund der Kompatibilität mit anderen Code dieser Klasse verwenden, können Sie Factory-Methoden für Implementierungen einfach genug bieten von Lambda-Ausdrücke zu profitieren, während sie noch Subclassing erlaubt:

public abstract class SessionExecutionBody { 

    public static SessionExecutionBody withResult(Supplier<?> s) { 
     Objects.requireNonNull(s); 
     return new SessionExecutionBody() { 
      @Override public Object execute() { return s.get(); } 
     }; 
    } 
    public static SessionExecutionBody withoutResult(Runnable r) { 
     Objects.requireNonNull(r); 
     return new SessionExecutionBody() { 
      @Override public void executeWithoutResult() { r.run(); } 
     }; 
    } 

    public Object execute() { 
     executeWithoutResult(); 
     return null; 
    } 

    public void executeWithoutResult() {} 
} 

, die Sie als

final HTTPDestination destination = sessionService.executeInLocalView(
    SessionExecutionBody.withResult(() -> { 
     userService.setCurrentUser(userService.getAdminUser()); 
     final String destinationName = 
      getConfigurationService().getConfiguration().getString(DESTINATION_PROPERTY); 
     return getHttpDestinationService().getHTTPDestination(destinationName); 
    }));