为什么这是错的:
Class<? extends Number> type = Integer.class;
ArrayList<type> = new ArrayList<>();
在给定类对象的情况下,是否无法实例化特定类型的类?
显然我永远不会直接这样做,这只是展示所需内容的一个例子。在我需要的实际代码中,我不知道该类型的名称。例如
public void createAList(Class<? extends Number> type)
{
ArrayList<type> toReturn = new ArrayList<>();
return toReturn;
}
答案 0 :(得分:7)
<T extends Number> ArrayList<T> createAList(Class<T> type)
{
ArrayList<T> toReturn = new ArrayList<>();
return toReturn;
}
ArrayList<Integer> intList = createAList(Integer.class);
答案 1 :(得分:4)
这不是你如何使用泛型。您不使用Class
对象,直接在代码中使用类名。
ArrayList<Integer> = new ArrayList<>();
答案 2 :(得分:3)
感受java Class(实际上也是通用的)对象和类名之间的区别。
您应该使用指定泛型类型的类名。
ArrayList<Number> = new ArrayList<>();
// ArrayList<Number.class> = new ArrayList<>(); <- WRONG
如果您只知道运行时的类型,请使用此方法:
public <T extends Number> void createAList(Class<T> type) {
ArrayList<T> toReturn = new ArrayList<>();
return toReturn;
}
答案 3 :(得分:2)
ArrayList<>
必须具有特定类型。您可以将该类型的对象或任何子类型放入其中。
所以使用
List<Number> = new ArrayList<Number>();
您可以将Integers
放入其中
注意我是如何使用左边的界面和等号右边的类的。这是最好的做法。
如果您想要一个只保留Integer
的列表(根据您的示例)@irreputable的答案是您最好的选择。此答案将保留Integer
,但不仅仅是Integer.
答案 4 :(得分:1)
从字面上看,其他人回答'关于如何实施createAList
的建议忽略了一些重要的事情:由于type erasure,这种方法毫无意义。
如果你想要一个List<? extends Number>
,你可以写下这个:
List<? extends Number> lst = new ArrayList<>();
如果你只想要List<?>
,你可以写:
List<?> lst = new ArrayList<>();
如果您在类型参数T
的范围内并想要List<T>
,则可以写:
List<T> lst = new ArrayList<>();
请注意,Class
对象与这些构造函数调用无关,就像其他答案中的方法一样。那是因为在运行时,ArrayList
实例不知道或不关心其引用在运行时具有的泛型类型。
答案 5 :(得分:1)
你甚至不需要传递参数:
public <T extends Number> ArrayList<T> createAList () {
return new ArrayList<T>();
}
虽然在调用时可能需要显式指定type参数:
ArrayList<Integer> intList = this.<Integer>createAList();
答案 6 :(得分:0)
ArrayList<type> = new ArrayList<>();
这条线错了。首先,你在这里错过了标识符(变量名称);其次,你混合了“类型”和“类”的概念。你可以delcare
ArrayList<Integer> list = new ArrayList<>();
但据你的说法,type = Integer.class
。显然,Integer
不等同于Integer.class
。同样地,你不能拥有Integer.class i = 1;
前一个是“类型”,第二个是“类”对象。
您可以创建一个通用方法:
public <T extends Number> List<T> createAList (Class<T> type) {
return new ArrayList<T>();
}