首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >未正确推断Java lamba参数类型

未正确推断Java lamba参数类型
EN

Stack Overflow用户
提问于 2018-08-09 23:46:27
回答 2查看 135关注 0票数 0

我正在尝试调用javafx上的这个方法:TableColumn.setOnEditCommit。此方法的定义如下:

代码语言:javascript
复制
public final void setOnEditCommit(EventHandler<CellEditEvent<S,T>> value) {
    // ...
}

正如您所看到的,它显式地需要一个CellEditEvent类型的EventHandler (它扩展了Event)。EventHandler的定义:

代码语言:javascript
复制
public interface EventHandler<T extends Event> extends EventListener {
    void handle(T event);
}

很明显,要调用setOnEditCommit (没有lamba),可以输入以下内容:

代码语言:javascript
复制
column.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent>() {
    public void handle(CellEditEvent event) {
        event.getTableView().doSomething();
    }
});

注意:getTableViewCellEditEvent__的方法,而不是Event__的方法。

到目前为止一切都很好。我遇到的问题是,如果不进行强制转换,使用lambda编写上述代码似乎是不可能的。也就是说,上面的lamba等价物是:

代码语言:javascript
复制
column.setOnEditCommit(event -> event.getTableView().doSomething());

问题就在这里。Lambda并不关心事件应该是一个CellEditEvent,因为setOnEditCommit方法显式地声明EventHandlerCellEditEvent是一个vararg。显然,当推断参数类型时,lamba检查EventHandler类定义,特别是<T extends Event>部分,然后决定T是一个Event,仅此而已,而不是t扩展Event。在这种情况下,抛出的错误是找不到方法'getTableView‘-因为Event类没有那个方法。

不仅如此,即使不明确声明参数类型也不起作用:

代码语言:javascript
复制
column.setOnEditCommit((TableColumn.CellEditEvent event) -> event.getTableView().doSomething());

导致错误的结果:

错误:(10,32) java:不兼容的类型: lambda表达式中的参数类型不兼容

我的问题是,为什么lambda不能正确地推断参数应该是T extends Event (在本例中是CellEditEvent),而不是Event,有什么方法可以解决这个问题吗?

完整示例:

代码语言:javascript
复制
import javafx.scene.control.TableColumn;
public class Main {
    public static void main(String[] args) {
        TableColumn column = null;
        column.setOnEditCommit(event -> event.getTableView());
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-10 01:25:34

显然,对TableColumn使用原始类型会导致此问题的发生。所以这将会起作用:

代码语言:javascript
复制
TableColumn<SomeClass, SomeOtherClass> column = null;
column.setOnEditCommit(event -> event.getTableView());

不仅如此,还有这个:

代码语言:javascript
复制
TableColumn<?, ?> column = null;
column.setOnEditCommit(event -> event.getTableView());

但这不会:

代码语言:javascript
复制
TableColumn column = null;
column.setOnEditCommit(event -> event.getTableView());
票数 1
EN

Stack Overflow用户

发布于 2018-08-10 00:24:22

编译器没有该类型信息。编译器拥有的唯一信息是:

代码语言:javascript
复制
public interface EventHandler<T extends Event> extends EventListener {
    void handle(T event);
}

现在你想像这样使用它:

代码语言:javascript
复制
import javafx.scene.control.TableColumn;
public class Main {
    public static void main(String[] args) {
        TableColumn column = null;
        column.setOnEditCommit(event -> event.getTableView());
    }
}

编译器应该如何确定事件的类型?类型CellEditEvent不会出现在任何地方。

在这种情况下,您必须显式指定所需的类型。

代码语言:javascript
复制
column.setOnEditCommit((TableColumn.CellEditEvent event) -> event.getTableView().doSomething());
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51771227

复制
相关文章

相似问题

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