Instantiating a Generic Class of Type <?>

烈酒焚心 提交于 2019-12-24 03:29:46

问题


I'm studying for the SCJP/OCPJP and I came across a sample question that seams strange to me.

The sample code instantiated two generic collections:

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

The "correct" answer to the question was that this code would compile but adding to either collection would produce a runtime error.

When I try to compile code like this I just get errors. The Java tutorial does not even show this type of code, it instead usually uses wildcards as a part of an upcast.

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

Are the two generic collections above even legitimate code? The second by my logic would only disallow interfaces. The first one looks completely useless. Why use a generic that makes no attempt at control?


回答1:


Check out the excellent Java generics tutorial PDF. More specifically the section about wildcards contains the answer to your question, and I quote

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

Since we don’t know what the element type of c stands for, we cannot add objects to it. The add() method takes arguments of type E, the element type of the collection. When the actual type parameter is ?, it stands for some unknown type. Any parameter we pass to add would have to be a subtype of this unknown type. Since we don’t know what type that is, we cannot pass anything in. The sole exception is null, which is a member of every type.




回答2:


If you want to declare Type at runtime, you can do something like this:

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());
}

}



回答3:


I answered this somewhat before in this answer. ? cannot be used in the instantiation. I'm not sure why it says the code would compile, none of the java compilers I have used would allow that. You could do what is shown above by the following:

List<?> list = new ArrayList();

That would compile and run, but you couldn't do:

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



回答4:


new produces a concrete instance of an object. The concrete instance can have only one type, including any generics. Knowing this, wildcards cannot work with new.



来源:https://stackoverflow.com/questions/8683137/instantiating-a-generic-class-of-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!