我正在尝试调用javafx上的这个方法:TableColumn.setOnEditCommit
。此方法的定义如下:
public final void setOnEditCommit(EventHandler<CellEditEvent<S,T>> value) {
// ...
}
正如您所看到的,它显式地需要一个CellEditEvent
类型的EventHandler
(它扩展了Event
)。EventHandler
的定义:
public interface EventHandler<T extends Event> extends EventListener {
void handle(T event);
}
很明显,要调用setOnEditCommit
(没有lamba),可以输入以下内容:
column.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent>() {
public void handle(CellEditEvent event) {
event.getTableView().doSomething();
}
});
注意:getTableView
是CellEditEvent
__的方法,而不是Event
__的方法。
到目前为止一切都很好。我遇到的问题是,如果不进行强制转换,使用lambda编写上述代码似乎是不可能的。也就是说,上面的lamba等价物是:
column.setOnEditCommit(event -> event.getTableView().doSomething());
问题就在这里。Lambda并不关心事件应该是一个CellEditEvent
,因为setOnEditCommit
方法显式地声明EventHandler
的CellEditEvent
是一个vararg。显然,当推断参数类型时,lamba检查EventHandler
类定义,特别是<T extends Event>
部分,然后决定T是一个Event
,仅此而已,而不是t扩展Event
。在这种情况下,抛出的错误是找不到方法'getTableView‘-因为Event
类没有那个方法。
不仅如此,即使不明确声明参数类型也不起作用:
column.setOnEditCommit((TableColumn.CellEditEvent event) -> event.getTableView().doSomething());
导致错误的结果:
错误:(10,32) java:不兼容的类型: lambda表达式中的参数类型不兼容
我的问题是,为什么lambda不能正确地推断参数应该是T extends Event
(在本例中是CellEditEvent
),而不是Event
,有什么方法可以解决这个问题吗?
完整示例:
import javafx.scene.control.TableColumn;
public class Main {
public static void main(String[] args) {
TableColumn column = null;
column.setOnEditCommit(event -> event.getTableView());
}
}
发布于 2018-08-10 01:25:34
显然,对TableColumn
使用原始类型会导致此问题的发生。所以这将会起作用:
TableColumn<SomeClass, SomeOtherClass> column = null;
column.setOnEditCommit(event -> event.getTableView());
不仅如此,还有这个:
TableColumn<?, ?> column = null;
column.setOnEditCommit(event -> event.getTableView());
但这不会:
TableColumn column = null;
column.setOnEditCommit(event -> event.getTableView());
发布于 2018-08-10 00:24:22
编译器没有该类型信息。编译器拥有的唯一信息是:
public interface EventHandler<T extends Event> extends EventListener {
void handle(T event);
}
现在你想像这样使用它:
import javafx.scene.control.TableColumn;
public class Main {
public static void main(String[] args) {
TableColumn column = null;
column.setOnEditCommit(event -> event.getTableView());
}
}
编译器应该如何确定事件的类型?类型CellEditEvent不会出现在任何地方。
在这种情况下,您必须显式指定所需的类型。
column.setOnEditCommit((TableColumn.CellEditEvent event) -> event.getTableView().doSomething());
https://stackoverflow.com/questions/51771227
复制相似问题