假设我有 a Type a
which is a java.util.TreeSet<T>
,已通过泛型参数化,由于类型擦除,我们看不到。我们还有Type b
一个 'java.lang.Integer'。我如何构造 a ParameterizedType
that is a java.util.TreeSet<java.lang.Integer>
?
或者,如果它更容易,我们可以使用原始java.util.TreeSet
类型。
假设我有 a Type a
which is a java.util.TreeSet<T>
,已通过泛型参数化,由于类型擦除,我们看不到。我们还有Type b
一个 'java.lang.Integer'。我如何构造 a ParameterizedType
that is a java.util.TreeSet<java.lang.Integer>
?
或者,如果它更容易,我们可以使用原始java.util.TreeSet
类型。
ParameterizedType
像这样实现:
public class MyParamType implements ParameterizedType {
private Type rawType;
private List<Type> paramTypes;
public MyParamType( Type raw ) {
this.rawType = raw;
}
public void addParamType( Type t ) {
paramTypes.add(t);
}
//for the interface methods, just return what you stored before
}
或多或少地为Type
. 如果您需要更多Type
关于非泛型类型实际应该实现什么的提示(它只是一个标记接口),请查看 JDK 源代码或查看调试器中的具体实例。
您对自己的问题给出了一半的答案。类型参数(在您的情况下为整数)是仅在编译时存在的擦除。因此,如果您想在Set<Integer>
开发代码时创建,您可以说:
Set<Integer> myset = new TreeSet<Integer>();
或者如果你是幸运的 Java 7 用户甚至更短:
Set<Integer> myset = new TreeSet<>();
然而,这一行将被编译为纯代码:
Set myset = new TreeSet();
所以,如果你想TreeSet<Integer>
在运行时创建实例,你只需要创建 plain 实例TreeSet
,例如 Class.forName(className).newInstance()
. 在这种情况下,类型参数Integer
无关紧要。
编辑:我刚刚阅读了您的评论并理解您为什么要问。如果你真的想要,你可以创建TreeSet
:的子类class IntegerTreeSet extends TreeSet<Integer>
。IntegerTreeSet
可以使用反射 API 发现参数类型。
此类可以静态创建(只需在代码中编写)或使用 Javassist 或 CGLIB 等工具动态创建。