2016-09-26 30 views
3

我有有兩種方法如下抽象類:如何編寫lambda表達式爲抽象類

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

    public void executeWithoutResult() {} 
} 

,我實現類,如下所示:

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

當我運行sonarLint其顯示主要問題將此匿名類轉換爲lambda表達式,但我無法找到相同的方式,我可以將該表達式轉換爲lambda表達式嗎?

+3

使用時無法從抽象類中創建一個lambda表達式。 Lambdas只能從功能接口創建。 – Jhonny007

回答

6

恐怕你不能。這不是一個用lambda風格實現它的抽象方法的函數接口。

我可以將該表達式轉換爲lambda表達式嗎?

你可以,如果你做如下修改:

@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

您可以將abstract class的子類不轉化成lambda表達式和審計工具,否則說,可以認爲有一個bug。由於Andrew Tobilko showed,在這裏使用lambda表達式的一種解決方案是將abstract class轉換爲interface

如果這不是一個選項,例如由於使用的是類與其他代碼兼容性,可以提供實現很簡單,從lambda表達式受益工廠方法,同時還允許子類:

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

,你可以作爲

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