繁体   English   中英

Java Generics 供应商接受方法中的不兼容类型

[英]Java Generics incompatible types in Supplier accept method

我有一个带有泛型参数的方法:

public static void addActionColumnAndSetSelectionListener(Grid<? extends UpdatableRecord<?>> grid,
                                                              EditDialog<? extends UpdatableRecord<?>> dialog,
                                                              Callback afterSave, Supplier<UpdatableRecord<?>> onNewRecord,
                                                              Consumer<? extends UpdatableRecord<?>> insteadOfDelete) {
        Button buttonAdd = new Button(grid.getTranslation("Add"));
        buttonAdd.addClickListener(event -> dialog.open(onNewRecord.get(), afterSave));

        grid.addComponentColumn(record -> {
            Button delete = new Button(grid.getTranslation("Delete"));
            delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
            delete.addClickListener(event -> {
                getBean(TransactionTemplate.class).executeWithoutResult(transactionStatus -> {
                    try {
                        if (insteadOfDelete != null) {
                            insteadOfDelete.accept(record);
                        } else {
                            getBean(DSLContext.class).attach(record);
                        }
                        record.delete();
                    } catch (DataAccessException e) {
                        Notification.show(e.getMessage());
                    }
                });
            });

            HorizontalLayout horizontalLayout = new HorizontalLayout(delete);
            horizontalLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.END);
            return horizontalLayout;
        }).setTextAlign(ColumnTextAlign.END).setHeader(buttonAdd);

        grid.addSelectionListener(event -> event.getFirstSelectedItem().ifPresent(record -> dialog.open(record, afterSave)));
    }

问题是行insteadOfDelete.accept(record); 不编译:

Error:(47, 52) java: incompatible types: org.jooq.UpdatableRecord<capture#1 of ?> cannot be converted to capture#2 of ? extends org.jooq.UpdatableRecord<?>

我不明白这个问题。 如果我改变

Consumer<? extends UpdatableRecord<?>> insteadOfDelete

Consumer<UpdatableRecord<?>> insteadOfDelete

它编译。

递归 generics 的乐趣... 在UpdatableRecord类型层次结构中使用它们可以看作是 jOOQ 的设计缺陷 您应该在方法的泛型类型变量中捕获通配符。 虽然它在使用时可能会在某种程度上起作用? extends UpdatableRecord<?> ? extends UpdatableRecord<?>甚至只是UpdatableRecord<?> ,我认为使用<R>类型变量,您将获得更清晰的代码。

这可能有效(我只更改了参数并添加了<R>类型变量,仅此而已):

public static <R extends UpdatableRecord<R>> void addActionColumnAndSetSelectionListener(
    Grid<R> grid,
    EditDialog<R> dialog,
    Callback afterSave, 
    Supplier<R> onNewRecord,
    Consumer<R> insteadOfDelete
) {
    Button buttonAdd = new Button(grid.getTranslation("Add"));
    buttonAdd.addClickListener(event -> dialog.open(onNewRecord.get(), afterSave));
    grid.addComponentColumn(record -> {
        Button delete = new Button(grid.getTranslation("Delete"));
        delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
        delete.addClickListener(event -> {
            getBean(TransactionTemplate.class).executeWithoutResult(transactionStatus -> {
                try {
                    if (insteadOfDelete != null) {
                        insteadOfDelete.accept(record);
                    } else {
                        getBean(DSLContext.class).attach(record);
                    }
                    record.delete();
                } catch (DataAccessException e) {
                    Notification.show(e.getMessage());
                }
            });
        });
        HorizontalLayout horizontalLayout = new HorizontalLayout(delete);
        horizontalLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.END);
        return horizontalLayout;
    }).setTextAlign(ColumnTextAlign.END).setHeader(buttonAdd);
    grid.addSelectionListener(event -> event.getFirstSelectedItem().ifPresent(
        record -> dialog.open(record, afterSave)));
}

此外,我已经删除了您的各个方法参数的协方差,因为我认为您可能不需要它。 否则,请记住Supplier是协变的, Consumer是逆变的。 这个答案很好地解释了它 这解释了你观察到当你有一个不变的消费者时突然编译的东西。

暂无
暂无

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

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