In the following sample code two classes EventA and EventB both implement the interface Historical. Java can automatically cast an EventA or EventB to Historical when one of these objects is passed as a parameter, as in the examineEvent method below. However, Java is no longer able to cast when a generic is introduced ie. from List<EventA> to List<Historical> -- Unless the target function (in this case findClosestValidEventIndex) is declared using List<? extends Historical>.
Can someone explain why this must be? It seems to me that the very use of an interface in a generic should automatically imply the <? extends Interface>.
public class SampleApplication {
public interface Historical {
public DateTime getDate();
}
public static class EventA implements Historical {
private DateTime date;
@Override
public DateTime getDate() {
return date;
}
}
public static class EventB implements Historical {
private DateTime date;
@Override
public DateTime getDate() {
return date;
}
}
private static int findClosestValidEventIndex(List<Historical> history, DateTime when) {
// do some processing
return i;
}
private static int examineEvent(Historical event){
return j;
}
public static void main(String[] args) {
DateTime target = new DateTime();
// AOK
EventA a = new EventA(target);
int idy = examineEvent(a);
// Type Error --- Unless
List<EventA> alist = new ArrayList<EventA>();
int idx = findClosestValidEventIndex(alist, target);
}
}