EventHandler.java:
public abstract class EventHandler<E extends EventArgs> {
public abstract void HandleEvent(Object sender, E e);
}
Observers.java:
public class Observers<E extends EventArgs> {
private CopyOnWriteArrayList<EventHandler<? extends E>> mListeners = new CopyOnWriteArrayList<EventHandler<? extends E>>();
public void dispatchEvent(Object sender, E args) {
if (mListeners != null) {
for (EventHandler<? extends E> listener : mListeners) {
listener.HandleEvent(sender, args);
}
}
}
}
The following line:
listener.HandleEvent(sender, args);
Causes:
The method HandleEvent(Object, capture#3-of ? extends E) in the type EventHandler is not applicable for the arguments (Object, E)
Does anybody how to fix this?
EDIT1
The reason ? super E
doesn't work for me is that I have the following method inside Observers
class:
public void addListener(EventHandler<? super E> listener) {
mListeners.add(listener);
}
And that causes:
The method add(EventHandler) in the type CopyOnWriteArrayList> is not applicable for the arguments (EventHandler)
EDIT2
The reason the change from ? super E
to E
doesn't work for me because of this:
X is not applicable for the arguments Y, when X extends Y
It was already like that but that didn't work neither :(
To use Java generics effectively, you must consider the following restrictions: Cannot Instantiate Generic Types with Primitive Types. Cannot Create Instances of Type Parameters. Cannot Declare Static Fields Whose Types are Type Parameters.
Only reference types can be used as type arguments. A parameterized type such as List<int> or Set<short> is illegal. Only reference types can be used for instantiation of generic types and methods.
Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.
Syntax of a Generic SetSet< T > set = new HashSet< T >(); Above syntax is a generalized way to use T to show the generic behavior of a Set which means that T can be replaced with any non-primitive like Integer, String, Double, Character, or any user-defined type.
Why are you declaring mListeners
to be ~ ? extends E
rather than just E
?
If you use
private CopyOnWriteArrayList<EventHandler<E>> mListeners = new CopyOnWriteArrayList<EventHandler<E>>();
It'll work.
Or adopt PECS (Producer Extends, Consumer Super). As others have suggested
private CopyOnWriteArrayList<EventHandler<? super E>> mListeners = new CopyOnWriteArrayList<EventHandler<? super E>>();
with related changes to the for
loop.
Edit: A fuller example. This shows no warnings or errors, and, based on what you've given, would work.
public static class Sandbox {
public static interface EventArgs {}
public static abstract class EventHandler<E extends EventArgs> {
public abstract void HandleEvent(Object sender, E e);
}
public static class Observers<E extends EventArgs> {
private CopyOnWriteArrayList<EventHandler<? super E>> mListeners
= new CopyOnWriteArrayList<EventHandler<? super E>>();
public void dispatchEvent(Object sender, E args) {
if (mListeners != null) {
for (EventHandler<? super E> listener : mListeners) {
listener.HandleEvent(sender, args);
}
}
}
public void addListener(EventHandler<? super E> listener) {
mListeners.add(listener);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With