I'm having some trouble in the following code.
public ArrayList<? extends IEvent> getEventsByDateRange(DateTime minStartTime, DateTime minEndTime)
{
ArrayList<? extends IEvent> returnedEvents = new ArrayList<GoogleEvent>();
returnedEvents.add(new GoogleEvent());
return (returnedEvents);
}
This return the following compilation error for the "returnedEvents.add(new GoogleEvent()); line of code":
The method add(capture#1-of ? extends IEvent) in the type ArrayList is not applicable for the arguments (GoogleEvent)
The declaration of the class GoogleEvent
is as follows:
public class GoogleEvent implements IEvent {...}
I know there are some tricky parts using generics in Java, thus the wild-cards but I can't seem to figure this out.
Thanks.
This is not allowed.
returnedEvents
contains a list ofGoogleEvent
objects and must not be allowed to accept objects that are notGoogleEvent
objects.Although in your example you happen to be passing a
GoogleEvent
, you are doing so by calling a version ofadd
that accepts anything that implementsIEvent
. Thatadd
method simply isn't allowed to be called, because it could result in the list storing things other thanGoogleEvent
.Java wildcards "edit out" methods that would break the rules in this way.
If you need to return that wildcarded list type, an
ArrayList<GoogleEvent>
satisfies it fine.Note this is a complete source file that compiles without error:
Why don't you write:
The solution:
The reason of your error is because the compiler is trying to do capture conversion.
In your case
returnedEvents
captures some unknown that extendsIEvent
(i.e. anything that extends/implementsIEvent
) and you're assigning it to a parameterized typeGoogleEvent
).The compiler sees,
returnedEvents.add(? extends IEvent)
which doesn't validate with a signature ofreturnedEvents.add(GoogleEvent)
as the capture placeholder is set onreturnedEvents
.You don't need to use
? extends IEvent
because by using onlyIEvent
, Java will dynamically bind theGoogleEvent
class. It's polymorphism.You cannot writer to a variable which is declared with
? extends ...
. Writing is only allowed when using? super ...
.This can be explained by the following example:
The short solution for you is to declare returnedEvents as
List<GoogleEvent>
.