首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >责任链模式中的Java 8流和泛型接口

责任链模式中的Java 8流和泛型接口
EN

Stack Overflow用户
提问于 2017-07-31 17:13:47
回答 1查看 1.3K关注 0票数 3

在一个运行在Java 8上的Spring Boot应用程序中,我想实现一个通用行为来处理不同类型的命令。

下面的代码说明了我心目中的解决方案。

一个通用的处理器模式

代码语言:javascript
运行
复制
public interface Processor<C extends Command> {
    TypeCommand getCommandType();
    void processCommand(C command);
}

public abstract class AbstractProcessor<C extends Command> implements Processor<C> {
    @Override
    public void processCommand(C command) {
        // Some common stuff 
        // ...

        // Specific process
        Result result = executeCommand(command);

        // More common stuff
        // ...
    }

    protected abstract Result executeCommand(C command);
}

@Component
public AddCommandProcessor extends AbstractProcessor<AddCommand> {

    @Override
    protected Result executeCommand(AddCommand addCommand) {
        // Execute command
        // ...
        return result; 
    }

    @Override
    public TypeCommand getCommandType() {
        return TypeCommand.ADD_COMMAND;
    }
}

命令:

代码语言:javascript
运行
复制
public abstract class Command {
    private final String uid;
    private final LocalDateTime creationDate;
    private final TypeCommand type;
    // Constructor and getters omited ...
}

public class AddCommand extends Command {
    private final Double amount;
    // Constructor and getters omited ...
}

具有责任链的服务:

代码语言:javascript
运行
复制
@Service
public class MyService {

    private final List<Processor<? extends Command>> processors;

    @Autowired
    public MyService(final List<Processor<? extends Command>> processors) {
        this.processors = processors;
    }

    public void processCommand(final Command command) {
        processors.stream()
            .filter(p -> command.getType() == p.getCommandType())
            .findFirst()
            .ifPresent(processor -> processor.processCommand(command));
    }
}

不幸的是,这段代码不能编译。这行代码:

代码语言:javascript
运行
复制
.ifPresent(processor -> processor.processCommand(command));

编译失败,并显示以下消息:

代码语言:javascript
运行
复制
processCommand(capture <? extends Command>) in Processor cannot be applied to (Command)

我看不到有任何其他方法可以达到预期的效果。我哪里错了?

非常感谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-31 20:43:10

您应该能够将Processor<? extends Command> processor上的泛型放到Processor processor中,这会将错误转换为有关原始类型的警告,您可以使用@SuppressWarnings("rawtypes")将其静音

代码语言:javascript
运行
复制
.ifPresent(processor -> ((Processor) processor).processCommand(command));

另一种方法是使processCommand成为泛型,并将Processor<? extends Command> processor向上转换为泛型类型,如下所示:

代码语言:javascript
运行
复制
public <C extends Command> void processCommand(final C command) {
    processors.stream()
        .filter(p -> command.getType() == p.getCommandType())
        .findFirst()
        .map(processor -> (Processor<C>) processor)
        .ifPresent(processor -> processor.processCommand(command));
}

这将给你一个警告,关于一个未经检查的强制转换,你可以用@SuppressWarnings("unchecked")静音。

如果返回特定TypeCommandCommand不是(第一个)返回相同Processor期望的类型的子类(例如,如果SubCommand返回TypeCommand.ADD_COMMAND,但不是AddCommand的子类),这两个方法都会抛出一个ClassCastException

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45411793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档