如何将泛型类传递给 Java 中的方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5683541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I pass a generic class to a method in Java?
提问by Anton
Suppose we have a function that creates objects given a particular class:
假设我们有一个函数可以创建给定特定类的对象:
public static <T> T createObject(Class<T> generic) {
try {
return generic.newInstance();
} catch (Exception ex) {
return null;
}
}
We can use the function easily to create instances of non-generic types.
我们可以轻松地使用该函数来创建非泛型类型的实例。
public static void main(String[] args) {
Foo x = createObject(Foo.class);
}
Is it possible to do the same thing with a generic type?
是否可以用泛型类型做同样的事情?
public static void main(String[] args) {
ArrayList<Foo> x = createObject(ArrayList<Foo>.class); // compiler error
}
采纳答案by Etienne de Martel
Generics, in Java, are implemented through type erasure.
Java 中的泛型是通过类型擦除实现的。
That means that an ArrayList<T>
, at run time, is an ArrayList
. The compiler simply inserts casts for you.
这意味着 anArrayList<T>
在运行时是 an ArrayList
。编译器只是为您插入强制转换。
You can test this with the following:
您可以使用以下方法对此进行测试:
ArrayList<Integer> first = new ArrayList<Integer>();
ArrayList<Float> second = new ArrayList<Float>();
if(first.getClass() == second.getClass())
{
// should step in the if
}
回答by Edwin Dalorzo
Also, as long as you are sure of what you are doing, and as long as you are pretty sure your code cannot incur heap pollution you can suppress the warning.
此外,只要您确定自己在做什么,并且只要您非常确定您的代码不会引起堆污染,您就可以抑制警告。
You may also take into consideration that your code cannot instantiate arrays, which by chance also requires an unchecked exception:
您可能还考虑到您的代码无法实例化数组,这也需要一个未经检查的异常:
@SuppressWarnings("unchecked")
public static <T> T[] createArray(Class<T> anyClass, int size){
T[]result = null;
try{
result = (T[]) Array.newInstance(anyClass, size);
}catch(Exception e){
e.printStackTrace();
}
return result;
}
This is how I used it:
这是我使用它的方式:
public static void main(String[] args) throws Exception{
@SuppressWarnings("unchecked")
List<String> jediNames = (List<String>) createObject(ArrayList.class);
jediNames.add("Obiwan");
String[] moreJedis = createArray(String.class, 10);
System.out.println(moreJedis.length);
moreJedis[0] = "Anakin";
}
回答by WhiteFang34
If you really need to you can force it to compile without errors or warnings:
如果你真的需要,你可以强制它编译而不会出现错误或警告:
@SuppressWarnings("unchecked")
ArrayList<Foo> x = (ArrayList<Foo>) createObject(ArrayList.class);
The only trouble is that at compile time it can't guarantee that createObject()
isn't adding objects to your ArrayList
that aren't of type Foo
. That's probably safe in your case, so you'll still get the benefit of generics without resorting to using ArrayList<?>
.
唯一的问题是在编译时它不能保证createObject()
不会向您添加ArrayList
不是 type 的对象Foo
。在您的情况下,这可能是安全的,因此您仍然可以获得泛型的好处,而无需求助于使用ArrayList<?>
.