方法中 Java 通配符泛型的返回类型



这可能是我第n次对泛型中的通配符感到困惑,所以我正在寻求您的帮助。请查看下面的代码。

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>。我的困惑是,TRunnable或其任何实现类的约束,这就是为什么我在调用m1时不能发送ArrayList<String>的原因。如果编译器足够聪明,知道这一点,为什么它不知道ArrayList<Thread>是这个方法m1的有效返回参数?

有人能帮忙吗?

谢谢!

让我解释一下,如果编译器允许您返回ArrayList<Thread>而不是ArrayList<T>,这意味着您可以用Runnable的另一个子类调用方法,但仍然会得到ArrayList<Thread>

例如,假设您有另一个Runnable实现为MyThread,并且您将方法m1调用为m1(new ArrayList<MyThread>),这意味着T=MyThread.class,同时您的方法返回RunnableArrayList<Thread>的另一个实现,这将导致RuntimeException

所以,泛型就是为什么在这里防止您将来出现运行时异常

正如@Andy和@Michael在评论中所说,实际返回变量的类型应该与函数签名中定义的返回类型完全相同。

它不能像您在代码中所写的那样只是它的一个子类型,因为如果您的函数的用户使用定义为RunnableT来调用它,那么您的返回类型将与实际的返回类型Collection<Runnable>不匹配。

所以你应该这样写你的函数:

static <T extends Runnable> Collection<T> m1(ArrayList<T> l) {
ArrayList<T> r = new ArrayList<>();
return r;
}

最新更新