在另一个SO post中,以下示例作为对OP的响应:
public static <E> void funct1(final List<E> list1, final E something)
{
list1.add(something);
}
public static void funct2(final List<?> list, final Object something)
{
list.add(something); // does not compile
}
我已经验证了funct1编译,而funct2没有编译。但是,我无法弄清楚原因。
答案 0 :(得分:8)
List<?>
是特定但未知类型的列表。编译器不允许对具有泛型类型参数的方法进行调用,因为无法保证类型安全。它可以是List<Integer>
或List<Foo>
,也不应该为其添加Object
。编译器必须使用编译器错误来阻止此调用,以保留泛型提供的类型安全性。
方法funct1
会进行编译,因为您始终可以向E
添加List<E>
;它是相同的类型引用:E
。
答案 1 :(得分:4)
rgettman是对的,但重要的是要声明这不仅适用于List
。它适用于所有通用类型。
如果使用通配符?
声明参数化类型的变量,则不能使用参数化类型声明的相应类型变量,因为您不知道它的值是什么。但是,您可以使用null
,因为null
可以在任何需要某个引用类型值的地方使用。
例如
public class Example {
public static void main(String[] str) throws Exception {
Parameterized<?> exp = new Parameterized<String>();
// below won't compile
/*
exp.something("tried my best");
exp.something(666);
*/
// below will compile
exp.something(null);
}
}
class Parameterized<T> {
public void something(T value) {}
}