[英]Java wildcard generics' return type in a method
这也许是我第九次对泛型通配符感到困惑,所以我寻求您的帮助。 请查看下面的代码。
public class MainClass {
public static void main(String[] args) {
ArrayList<Thread> l = new ArrayList<>();
l.add(new Thread());
l.add(new Thread());
m1(l);
}
static <T extends Runnable> Collection<T> m1(ArrayList<T> l) {
ArrayList<Thread> r = new ArrayList<>();
return r;
}
}
当我调用m1时,我可以传递ArrayList<Runnable>
或其任何实现类,并且它可以工作。 到目前为止,一切都很好。 现在在方法m1
,Im无法返回ArrayList<Thread>
或ArrayList< Runnable>
因为返回类型为Collection<T>
。 我的困惑是, T
受Runnable
或其任何实现类的限制,这就是为什么在调用m1时无法发送ArrayList<String>
的原因。 如果编译器足够聪明,知道为什么,为什么不知道ArrayList<Thread>
是此方法m1
的有效返回参数?
有人可以帮忙吗?
谢谢!
让我解释一下,如果编译器允许您返回ArrayList<Thread>
而不是ArrayList<T>
则意味着您可以使用Runnable的另一个子级调用方法,但仍然会得到ArrayList<Thread>
。
例如,假设您有另一个Runnable实现为MyThread
并且将方法m1
称为m1(new ArrayList<MyThread>)
,这意味着T=MyThread.class
,同时您的方法返回了Runnable ArrayList<Thread>
另一个实现ArrayList<Thread>
这将导致RuntimeException
因此,泛型就是这里防止您将来发生运行时异常的原因
正如@Andy和@Michael在评论中所说,返回的实际变量的类型应与函数签名中定义的返回类型完全相同。
它不能只是您在代码中编写的子类型,因为例如,如果函数的用户使用定义为Runnable
T
调用它,则您的返回类型将与实际的返回类型不匹配,即Collection<Runnable>
。
因此,您应该这样编写函数:
static <T extends Runnable> Collection<T> m1(ArrayList<T> l) {
ArrayList<T> r = new ArrayList<>();
return r;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.