0

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.

phreed
  • 1,759
  • 1
  • 15
  • 30
  • `List as` is invalid. List has only one type parameter. Did you mean `List> as`? – Thiyagu Jul 20 '18 at 16:21
  • @user7 yes, that is what I meant. I can give specific code examples, but here is a link to the actual system and an example file. https://github.com/babeloff/fql/blob/master/src/catdata/aql/exp/InstExp.java – phreed Jul 20 '18 at 16:25

1 Answers1

1

If you only care about the return value of foo(), then you could use this:

List<A<String, ?, ?>> as = ...;

That will let you store A or any subtype of A for which the type argument to T is String, but with anything for U and V. So:

as.add(new A<String, String, Integer>()); // fine
as.add(new B<String>()); // fine
as.add(new C<Integer>()); // fine

as.add(new A<Double, String, Integer>()); // won't compile

However, you won't be able to call methods of A which have parameters of type U and V. If that's a problem, then it seems like you have to redesign somehow.

Possibly also see:

Radiodef
  • 37,180
  • 14
  • 90
  • 125