java方法不适用于参数

时间:2018-02-08 19:44:31

标签: java generics arguments wildcard

我看不出为什么 size(test); 无法编译。有人可以帮我理解吗?

public class TestContainer<T extends Object> {
}

public class Main {
    public static int size(List<TestContainer<?>> list) {
        return list.size(); 
    }

    public static void main(String[] args) {
        List<TestContainer<Object>> test = new ArrayList<TestContainer<Object>>();
        size(test); // this does not compile
        test.size(); // of course this works fine
    }
}

2 个答案:

答案 0 :(得分:0)

只有当List参数声明使用上限通配符参数化时,具有as参数的通用List的方法才能接受泛型类型的子类。

您不能在此处为<? extend T>声明任何upper bounded wildcard List<TestContainer>):

public static int size(List<TestContainer<?>> list) {
    return list.size(); 
}

因此,您只能将此确切类型作为参数传递:

List<TestContainer<?>>

为了实现你想要的,你应该这样写:

public static int size(List<? extends TestContainer<?>> list) {
    return list.size(); 
}

请注意,上限有界通配符旨在确保传递的List的类型安全性 因此,在方法内部,您无法添加任何内容,只能null 但对于您的用例(返回列表的大小),这不是问题。

答案 1 :(得分:0)

List<TestContainer<Object>>不是List<TestContainer<?>>

TestContainer<Integer>TestContainer<?>。因此,您可以向TC<Integer>添加List<TC<?>>。同样,您可以将TC<String>添加到List<TC<?>>

但是,TC<Integer>不是TC<Object>(因为泛型在Java中是不变的),因此您不能被允许向{{1}添加TC<Integer> }}。因此,List<TC<Object>>不是List<TC<Object>>

如果你这样做是为了你不能向List添加任何东西(除了文字null) - 通过制作方法参数List<TC<?>>(或List<? extends TC<?>>,如果你对元素真的不感兴趣) - 它是安全的,因此是允许的。