we have a method more or less like the following. however we currently return List which in function bla() would return List<Bar>
at runtime.
I'm looking for a way to make both
List<Interface> = troubleFuction(foo, bar.getCLass());;
and
List<Bar> = troubleFuction(foo, bar.getCLass());;
possible. basicaly i want it to return List which would be compatible with interface however this gives the following error
*Type mismatch: cannot convert from List<capture#3-of ? extends Bar>
List<capture#3-of ? extends Bar>
to List<Interface>*
is there any way to make this return type possible or does runtime erasure make this impossible
public <T1 extends Interface, T2 extends Interface> List<"problem"> troubleFunction( T1 in, Class<T2> clazz) {
return in.doStuffWhichGeneratesAlistOF(clazz)
}
public void bla() {
Foo foo = new Foo(); // implements interface
Bar bar = new Bar(); // implements interface
List<Interface> ifaces = toubleFuction(foo, bar.getCLass());
List<Bar> mustAlsoWork = toubleFuction(foo, bar.getCLass());
}
edit: in a lot of the existing code base the method is called like
List<Bar> result = troubleFunction(List<Interface> list, Bar.class);
thus this return type must stay compatible (rewrite/re-factor is not an option)
essentially i want the method to return List <? super Bar>
<? super Bar>
if called as
troublefunction(foo, Bar.class);
and List<? super Foo>
List<? super Foo>
when called as
troublefunction(foo, Bar.class);
Generally speaking in situations like this, you need to explicitly pass a Class object in (generically parameterised) which is used for the return value.
However it looks like you've done this already in your case, so would it not work for troubleFunction
to be declared to return List<T2>
? Alternatively, if you want to keep it general then have it return List<? extends Interface>
List<? extends Interface>
.
You're not giving us enough information to really tell what you need to do. For example, you didn't give us the type signature of doStuffWhichGeneratesAlistOF()
or tell us what it does. And you didn't tell us what the type of the " in
" argument has to do with all of this.
Sure, it's possible to have the return type of a method be generic. For example,
public <T extends Interface> List<T> troubleFunction(Interface in, Class<? extends T> clazz) {
List<T> result = new ArrayList<T>();
result.add(clazz.newInstance());
return result;
}
And then you could call the method directly like this and it would work (you don't need to specify the type parameter explicitly because it's inferred from the assignment):
List<Interface> iface = this.troubleFunction(foo, bar.getCLass());
But seeing as how in your code above you return the result of in.doStuffWhichGeneratesAlistOF(clazz)
, you would probably have to make the return type of that method generic also. But I can't really help you on that because we don't have any information on that method.
i've looked at this again and the problem was that i wanted to use a 'super' return type the signature i was looking for was more or less:
public <T1 extends interface, T2 super T1> List<T2> getAList(Class<T1> clazz);
which is not possible
As I understand it, the argument types are looked at before the target type to infer the generic arguments. So, I guess you need to explicitly specify the generic arguments, which I think goes something like this:
List<Interface> iface = this.<Interface>troubleFunction(foo, bar.getCLass());
where
public <T extends Interface> List<T> troubleFunction(
T in, Class<? extends T> clazz
) {
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.