Consider a Java generic class hierarchy of the following rawtype form.
class A ...
class B extends A ...
class C extends A ...
With a method in class A and overridden in B and C.
String foo() ...
String bar(A a) ...
We can make the following calls successfully.
String r = (new B()).foo();
String r = (new B()).bar(new C());
The real goal here is to save instances of A in a container and process them all without regard for which sort of A we have.
A fred;
List as = new LinkedList();
for (A a : as) ... fred.bar(a); ...
Objects of classes B and C can be constructed and passed to foo with no problem. Now we introduce generics.
class A<T,U,V> ...
class B<T> extends A<T,Void,Object> ...
class C<N> extends A<String,Void,Object> ...
With a method in class A and overridden in B and C.
T foo() ...
Then we make the following reasonable calls.
String r = (new A<String,Void,Object>()).foo();
String r = (new B<String>()).foo();
String r = (new C<Integer>()).foo();
String r = (new B<String>()).foo();
String r = (new B<String>()).bar(new C<Integer>());
The real goal here is to save instances of A in a container and process them all without regard for which sort of A we have.
A<String,String,Integer> fred;
List<A<String,String,Integer>> as = new LinkedList<>();
for (A a : as) ... fred.bar(a); ...
These decisions makes it impossible to load objects of types B and C into the "as" list, due to conflicting types in the generic template.
Note this is endemic an existing piece of software for which I am trying to clear up warning.