简体   繁体   English

如何为抽象类编写lambda表达式

[英]how to write lambda expression for the abstract class

I have abstract class which have two methods as follows: 我有抽象类,有两个方法如下:

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

   public void executeWithoutResult() {}
} 

and I implement the class as follows: 我按如下方式实现了这个类:

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

When I run sonarLint its showing major issue convert this anonymous class to lambda expression but I am unable to find the way to right the same , Can I convert that expression into a lambda? 当我运行sonarLint时,它显示的主要问题是将这个匿名类转换为lambda表达式,但是我无法找到相同的方法,我可以将该表达式转换为lambda吗?

I'm afraid you can't. 我怕你不能。 That is not a functional interface with one abstract method to implement it in the lambda style. 这不是一个功能接口,有一个抽象方法以lambda样式实现它。

Can I convert that expression into a lambda? 我可以将该表达式转换为lambda吗?

You could if you make the following changes: 您可以进行以下更改:

@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 ...; })

You can't convert the subclass of an abstract class into a lambda expression and an audit tool saying otherwise can be considered to have a bug. 您不能将abstract class的子abstract class转换为lambda表达式,否则可以将审计工具视为具有错误。 As Andrew Tobilko showed , one solution to use a lambda expression here, would be converting the abstract class into an interface . 正如Andrew Tobilko所示 ,在这里使用lambda表达式的一种解决方案是将abstract class转换为interface

If that's not an option, eg due to compatibility with other code using that class, you may offer factory methods for implementations simple enough to benefit from lambda expressions, while still allowing subclassing: 如果这不是一个选项,例如由于与使用该类的其他代码的兼容性,您可以提供简单的实现工厂方法以从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() {}
}

which you can use as 你可以用作

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM