Java 如何从泛型类型参数获取`.class` 属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18255117/
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 do I get the `.class` attribute from a generic type parameter?
提问by John Gowers
The accepted answer to this questiondescribes how to create an instance of T
in the Generic<T>
class. This involves passing in a Class<T>
parameter to the Generic
constructor and callin the newInstance
method from that.
这个问题的公认答案描述了如何T
在Generic<T>
类中创建一个实例。这涉及将Class<T>
参数传递给Generic
构造函数并newInstance
从中调用方法。
A new instance of Generic<Bar>
is then created, and the parameter Bar.class
is passed in.
Generic<Bar>
然后创建一个新实例,并Bar.class
传入参数。
What do you do if the generic type parameter for the new Generic
class is not some known class like Bar
but is itself a generic type parameter? Suppose I had some other class Skeet<J>
and I wanted to create a new instance of Generic<J>
from inside that class. Then, if I try to pass in J.class
I get the following compiler error:
如果新Generic
类的泛型类型参数不是某个已知类,Bar
但它本身就是泛型类型参数,你会怎么做?假设我有一些其他类,Skeet<J>
并且我想Generic<J>
从该类内部创建一个新实例。然后,如果我尝试传入,则会J.class
出现以下编译器错误:
cannot select from a type variable.
Is there any way around this?
有没有办法解决?
The specific bit of code triggering the error for me is:
对我来说触发错误的特定代码是:
public class InputField<W extends Component & WidgetInterface>
extends InputFieldArray<W>
{
public InputField(String labelText)
{
super(new String[] {labelText}, W.class);
}
/* ... */
}
public class InputFieldArray<W extends Component & WidgetInterface>
extends JPanel
{
/* ... */
public InputFieldArray(String[] labelText, Class<W> clazz)
throws InstantiationException, IllegalAccessException
{
/* ... */
for (int i = 0 ; i < labelText.length ; i++) {
newLabel = new JLabel(labelText[i]);
newWidget = clazz.newInstance();
/* ... */
}
/* ... */
}
/* ... */
}
The error happens, because I can't write W.class
. Is there some other way of passing in the same information?
错误发生了,因为我不能写W.class
. 是否有其他方式传递相同的信息?
采纳答案by Paul Bellora
Using .class
on a type parameter isn't allowed - because of type erasure, W
will have been erasedto Component
at runtime. InputField
will need to also take a Class<W>
from the caller, like InputFieldArray
:
使用.class
一个类型参数是不允许的-因为类型擦除,W
将被清除,以Component
在运行时。InputField
还需要Class<W>
从调用者那里获取 a ,例如InputFieldArray
:
public InputField(String labelText, Class<W> clazz)
{
super(new String[] {labelText}, clazz);
}
回答by nanofarad
W may not be available due to type erasure. You should require that a Class<W>
is passed into the method. You get a class object and its generic ensures that only W
and no subclass is passed in, due to covariance.
由于类型擦除,W 可能不可用。您应该要求将 aClass<W>
传递到方法中。你得到一个类对象,它的泛型确保只有W
和没有子类被传入,由于协方差。
public InputField(String labelText, Class<W> cls)
{
super(new String[] {labelText}, cls);
}
will take W.class
but not WSubtype.class
.
会W.class
但不会WSubtype.class
。
回答by jdex
If you're using the GSON
library, you can get the type of T
easily by using TypeToken
. The class documentation is available here:
如果您正在使用该GSON
库,则可以T
通过使用TypeToken
. 类文档可在此处获得:
I did it like this:
我是这样做的:
This is my class definition:
这是我的类定义:
public class ManagerGeneric <T> {}
This is in my method:
这是我的方法:
// Get the type of generic parameter
Type typeOfT = new TypeToken<T>(){}.getType();
// Deserialize
T data = gson.fromJson(json, typeOfT);