【问题标题】:how to write lambda expression for the abstract class如何为抽象类编写 lambda 表达式
【发布时间】:2016-09-26 09:23:54
【问题描述】:

我有一个抽象类,它有两种方法如下:

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 吗?

【问题讨论】:

  • 您不能从抽象类创建 lambda 表达式。 Lambda 只能从函数式接口创建。

标签: java lambda java-8 anonymous-class


【解决方案1】:

恐怕你不能。这不是一个功能接口,只有一个抽象方法来以 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 表达式,否则审计工具会被视为存在错误。作为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);
        }));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-28
      • 1970-01-01
      • 2010-11-07
      • 1970-01-01
      • 1970-01-01
      • 2011-05-05
      • 2012-06-14
      • 2021-12-10
      相关资源
      最近更新 更多