为何JavaFX的Node.setOnKeyPressed使用? super KeyEvent作为EventHandler泛型?
EventHandler<? super KeyEvent> Instead of EventHandler<KeyEvent> Great question! This is a perfect illustration of how Java generics' PECS (Producer-Extends, Consumer-Super) principle applies to real-world APIs like JavaFX. Let's break this down step by step to understand why the super wildcard is used here.
The "Consumer" Role of EventHandler
When you pass anEventHandlertosetOnKeyPressed, that handler is going to consume aKeyEvent(or any parent type ofKeyEvent, likeInputEventorEvent). The PECS rule tells us that for code that takes in values (consumers), we should use? super Tto maximize flexibility while maintaining type safety.Reusability of Handlers
Suppose you have a generic event handler that works for anyEvent—say, one that logs every event's timestamp:EventHandler<Event> eventLogger = event -> { System.out.println("Event fired at: " + System.currentTimeMillis()); };If
setOnKeyPressedonly acceptedEventHandler<KeyEvent>, you couldn't pass thiseventLoggerdirectly—you'd have to create a new handler specifically forKeyEventthat wraps it. But withEventHandler<? super KeyEvent>, this generic handler works perfectly, becauseKeyEventis a subclass ofEvent, and the handler can safely consume it.Compatibility with Parent Event Types
What if you have anEventHandler<InputEvent>that handles all input events (mouse, keyboard, etc.)? SinceKeyEventextendsInputEvent, this handler is also compatible withsetOnKeyPressedwhen using thesuperwildcard. This lets you reuse broader handlers for specific event types without rewriting redundant code.Avoiding Unnecessary Restrictions
If the API usedEventHandler<KeyEvent>instead, it would artificially restrict developers to only using handlers that explicitly declareKeyEventas their type. Thesuperwildcard removes this restriction, allowing any handler that can handleKeyEventor any of its parent types to be used. This aligns with good API design principles—giving users more flexibility without sacrificing type safety.
At the end of the day, this design choice is all about making your code more flexible and reusable. By using ? super KeyEvent, JavaFX lets you leverage existing handlers for broader event types instead of forcing you to create redundant, type-specific handlers for every single event callback.
内容的提问来源于stack exchange,提问作者user5182503

