I have this situation, I tried to create an example of it, and would like to see if there is any elegant way to fix it.
Suppose I have some Interface Displayable, and implementing Classes :Person and Car, and I have generic Converter class declared like this:
public interface Converter<T extends Displayable> {
boolean canConvert(Displayable o);
String convert(T o);
T decode(String s);
boolean canRevert(String s);
}
Suppose I have Implementations of this
public class CarConverter implements Converter<Car> { ... }
and
public class PersonConverter implements Converter<Person> { ... }
now in my useage I have a list of Displayable, and a list of converters, and I would like to convert and revert the Displayables:
List<Displayable> ds = new ArrayList<Displayable>();
ds.add(new Person("ma",12));
ds.add(new Person("fa",43));
ds.add(new Car());
ds.add(new Car());
ds.add(new Person("Sol",58));
List<Converter>cs = new ArrayList<Converter>();
cs.add(new CarConverter());
cs.add(new PersonConverter());
ArrayList<String> displays = new ArrayList<String>();
for(Displayable d:ds) {
for(Converter c:cs) {
if(c.canConvert(d)) {
displays.add(c.convert(d));
break;
}
}
}
List<Displayable> ret = new ArrayList<Displayable>();
for(String display : displays) {
for(Converter c:cs) {
if(c.canRevert(display)) {
Displayable d = c.decode(display);
ret.add(d);
}
}
}
the annoying bit is that I had to declare a list Converters, loosing the generics.
List<Converter>
I get a syntax error if I try to declare
List<Convert<Displayable>>
and then I get a lot of warnings.
You can do this, you just need to make a slight change to your list declaration:
This will work for you. The key thing to bear in mind here is that, you can’t rely on inheritance in the nested type parameters, you need to declare the extension with
extends.If you have
List<Converter<Displayable>>you can only addConverter<Displayable>instances to that list, notConverter<SomethingThatExtendsDisplayable>>.