从泛型函数返回泛型类型

时间:2009-05-26 14:48:52

标签: java generics super return-type

我们的方法或多或少如下。 但是我们目前返回List 函数bla()中的函数将在运行时返回List<Bar>

我正在寻找一种方法来制作两者

List<Interface> =  troubleFuction(foo, bar.getCLass());;

List<Bar> = troubleFuction(foo, bar.getCLass());;

可能的。 基本上我希望它返回与界面兼容的List 但是这会产生以下错误

*类型不匹配:无法从List<capture#3-of ? extends Bar>转换为List<Interface>*

有什么方法可以使这种返回类型成为可能,或者运行时擦除是否使这个不可能

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());
}

编辑: 在许多现有的代码库中,该方法被称为

List<Bar> result = troubleFunction(List<Interface> list, Bar.class);

因此这个返回类型必须保持兼容(重写/重新因子不是一个选项)

基本上我希望该方法在调用

时返回List <? super Bar>
troublefunction(foo, Bar.class);

和 调用时为List<? super Foo>

troublefunction(foo, Bar.class);

4 个答案:

答案 0 :(得分:1)

一般来说,在这种情况下,您需要显式传递一个用于返回值的(通用参数化)对象。

但是看起来你已经在你的情况下已经这样做了,那么宣布troubleFunction被宣布为返回List<T2>是不行的呢?或者,如果你想保持一般性,那么让它返回List<? extends Interface>

答案 1 :(得分:1)

你没有给我们足够的信息来真正告诉你需要做什么。例如,您没有向我们提供doStuffWhichGeneratesAlistOF()的类型签名或告诉我们它的作用。你没有告诉我们“in”论证的类型与所有这些有什么关系。

当然,可能使方法的返回类型是通用的。例如,

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;
}

然后你可以像这样直接调用方法,它可以工作(你不需要明确指定类型参数,因为它是从赋值中推断出来的):

List<Interface> iface = this.troubleFunction(foo, bar.getCLass());

但是看看你上面的代码中如何返回in.doStuffWhichGeneratesAlistOF(clazz)的结果,你可能还必须使该方法的返回类型也是通用的。但我无法真正帮助你,因为我们没有关于该方法的任何信息。

答案 2 :(得分:0)

据我了解,在目标类型之前查看参数类型以推断泛型参数。所以,我想你需要明确指定泛型参数,我认为这是这样的:

List<Interface> iface = this.<Interface>troubleFunction(foo, bar.getCLass());

,其中

public <T extends Interface> List<T> troubleFunction(
    T in, Class<? extends T> clazz
) {

答案 3 :(得分:0)

我再次看了这个,问题是我想使用'超级'返回类型 我正在寻找的签名或多或少:

 public <T1 extends interface, T2 super T1> List<T2> getAList(Class<T1> clazz); 

这是不可能的