簡體   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