Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics: Method X is not applicable for the arguments

Tags:

java

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 :(

like image 658
Caner Avatar asked Nov 15 '11 13:11

Caner


People also ask

What is not allowed for generics Java?

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.

Which types can be used as arguments of generics?

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.

What is generics method in Java?

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.

How do I set generics in Java?

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.


1 Answers

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);
        }        
    }
}
like image 105
ptomli Avatar answered Oct 21 '22 19:10

ptomli