Java Generics:关于SO的示例说明

时间:2014-02-27 22:44:26

标签: java generics

在另一个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没有编译。但是,我无法弄清楚原因。

2 个答案:

答案 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) {}
}