The fact that the source will be a JSpinner
is known at runtime. The kind of “automatic type casts” you describe are possible with generics at compile time, but at that time there is no telling where the listener might end up. For example, you could take your spinner, obtain a list of all listeners, and then add these listeners to another widget like a check box. There is nothing in your code to tell the compiler at compile time that this won't happen, so there is nothing to tell the compiler that the source will always be a spinner.
It would theoretically be possible to use generics in some way. You could have a ChangeEvent<T>
for changes originating from a component of class T
. You could have a ChangeListener<T>
with a method stateChanged(ChangeEvent<? extends T>)
. But then what would be the type for all listeners of a given component of class T
? If it were List<ChangeEvent<T>>
then you wouldn't be allowed to add a generic ChangeListener<Object>
to that list. So it would have to be List<ChangeEvent<? super T>>
. But if you had such a list in any component, then it would be the same type for all derived components, instead of a more specific type like the generics approach would suggest.
So on the whole I think this generics approach would make the code a lot harder to write and maintain, would likely leave loopholes in some places, would probably be horrible in terms of backwards compatibility, and on the whole would not be worth the effort.