繁体   English   中英

实例化类型的泛型类<?>

[英]Instantiating a Generic Class of Type <?>

我正在为SCJP / OCPJP学习,遇到一个示例问题,这个问题对我来说很奇怪。

该示例代码实例化了两个通用集合:

List<?> list = new ArrayList<?>();
List<? extends Object> list2 = new ArrayList<? extends Object>();

这个问题的“正确”答案是该代码可以编译,但是添加到任何一个集合中都会产生运行时错误。

当我尝试像这样编译代码时,我只会得到错误。 Java教程甚至没有显示这种类型的代码,而是通常使用通配符作为转换的一部分。

Collection<?> c = new ArrayList<String>();

上面的两个通用集合甚至是合法代码吗? 根据我的逻辑,第二个将只禁止接口。 第一个看起来完全没用。 为什么要使用不尝试控制的泛型?

查看出色的Java泛型教程PDF 更具体地说,有关通配符的部分包含您问题的答案,我引用

Collection<?> c = new ArrayList<String>();
c.add( new Object() );

由于我们不知道c的元素类型代表什么,因此无法向其添加对象。 add()方法采用类型E参数,即集合的元素类型。 当实际类型参数是? ,代表某种未知类型。 我们传递来添加的任何参数都必须是该未知类型的子类型。 由于我们不知道是什么类型,因此无法传递任何内容。唯一的例外是null ,它是每种类型的成员。

如果要在运行时声明Type,则可以执行以下操作:

public class Clazz1<T> {

private final List<T> list = new ArrayList<T>();

private List<T> getList() {
    return list;
}

/**
 * @param args
 */
public static void main(String[] args) {
    Clazz1<Integer> clazzInt = new Clazz1<Integer>();
    clazzInt.getList().add(2);
    System.out.println(clazzInt.getList());

    Clazz1<String> clazzString = new Clazz1<String>();
    clazzString.getList().add("test");
    System.out.println(clazzString.getList());
}

}

我之前在答案中对此有所回答。 ? 不能在实例化中使用。 我不确定为什么它会说代码可以编译,我使用的所有Java编译器都不允许。 您可以通过以下方法执行上面显示的操作:

List<?> list = new ArrayList();

那可以编译并运行,但是您不能这样做:

list.add("hello world"); //This wouldn't compile

new产生对象的具体实例。 具体实例只能具有一种类型,包括任何泛型。 知道这一点,通配符就不能与new

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM