0 java generics events javafx-8
EventType系统在JavaFX中非常混乱.我认为原因是设计人员决定使EventType类本身通用.
是否有任何实际用途,或者这只是一种确保类型安全的模糊形式?
我想象只有当泛型类型返回到调用类时才会使类成为通用的.否则有什么意义呢?
有Event类,即子类Event,定义该类的特定方法.例如MouseEvent定义了可以用于查询鼠标的坐标当事件发生时的各种方法(getX(),getY(),getSceneX(),getScreenX()等); ScrollEvent定义方法来查询滚动的量和方向:getDeltaX(),getDeltaY(),等等).
EventType是一个更细粒度的对象,它指定发生了什么.因此,常数EventType类包括MOUSE_CLICKED,MOUSE_PRESSED,KEY_TYPED,SCROLL_STARTED,等.这些值中的每一个与特定的相关联的Event子类.
事件登记方法是addEventHandler(...).此方法有两个参数:a EventType(要监听的事件类型)和a EventHandler.由于EventHandler显而易见的原因,它是通用的:通过定义一个EventHandler<T extends Event>定义一个handle(T event)获取适当事件对象的方法,然后您可以以特定于类型的方式进行查询.(例如,EventHandler<MouseEvent>有一个handle(MouseEvent event)方法,可以查询鼠标的坐标等).
现在,它清楚地才有意义,注册一个EventHandler<T>用于EventType与该相关Event子类T.此外,希望允许编译器强制执行此操作.通过使EventType类通用:EventType<T extends Event>,我们可以让编译器强制执行此规则.MOUSE_CLICKED它不仅仅是一个实例EventType,它是一个实例EventType<MouseEvent>.由于addEventHandler(...)方法的签名是addEventHandler(EventType<T>, EventHandler<T>),编译器强制处理程序是"与事件类型相同的事件类".
当你将它与使用lambdas结合起来时(或者我认为特别是类型推断),它变得非常强大:
node.addEventHandler(MOUSE_CLICKED, e -> {...});
Run Code Online (Sandbox Code Playgroud)
因为MOUSE_CLICKED具体是EventType<MouseEvent>,编译器能够推断出由lambda定义的事件处理程序是一个EventHandler<MouseEvent>,因此它e是一个MouseEvent.所以编译器现在可以推断出来了
node.addEventHandler(MOUSE_CLICKED, e -> System.out.println(e.getX()));
node.addEventHandler(KEY_TYPED, e -> System.out.println(e.getText()));
Run Code Online (Sandbox Code Playgroud)
是合法的,但是
node.addEventHandler(MOUSE_CLICKED, e -> System.out.println(e.getText()));
Run Code Online (Sandbox Code Playgroud)
不是.如果EventType不是通用的,这是不可能的.
(没有lambdas也是如此,但不那么简洁的语法也没有推动回归点.但是如果EventType不是通用的,那么编译器就没有办法拒绝
node.addEventHandler(MOUSE_CLICKED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) { }
});
Run Code Online (Sandbox Code Playgroud)
同样,MOUSE_CLICKED有类型的事实EventType<MouseEvent>意味着这将无法编译.)
从技术上讲,EventType它被用作"运行时类型令牌".它不仅用于说明我们感兴趣的事件,还用于处理事件的事件处理程序类型.使用泛型的其他示例包括Class<T>:请参阅Java教程的这一部分以进行简要讨论.