2016-09-26 3 views
3

У меня есть абстрактный класс, который есть два метода следующим образом:как написать лямбда-выражения для абстрактного класса

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 ИТС показывая главную проблему, превратите этот анонимный класс в выражение лямбда, но я не могу найти способ сделать то же самое, могу ли я преобразовать это выражение в лямбда?

+3

Вы не можете сделать лямбда-выражение из абстрактного класса. Lambdas можно создавать только из функциональных интерфейсов. – Jhonny007

ответ

6

Боюсь, вы не можете. Это не функциональный интерфейс с одним абстрактным методом для его реализации в стиле лямбда.

Можно ли преобразовать это выражение в лямбда?

Вы можете, если вы сделаете следующие изменения:

@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 в лямбда-выражения и инструмент аудита говоря иначе может рассматриваться как есть ошибка. Поскольку Andrew Tobilko showed, одно из решений для использования выражения лямбда здесь, будет преобразовывать abstract class в interface.

Если это не вариант, например. благодаря совместимости с другим кодом, используя этот класс, вы можете предложить фабричные методы для реализации достаточно простой, чтобы извлечь выгоду из лямбда-выражения, в тот же время позволяя подклассы:

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); 
    })); 
Смежные вопросы