假设我有 a Type awhich is a java.util.TreeSet<T>,已通过泛型参数化,由于类型擦除,我们看不到。我们还有Type b一个 'java.lang.Integer'。我如何构造 a ParameterizedTypethat is a java.util.TreeSet<java.lang.Integer>?
或者,如果它更容易,我们可以使用原始java.util.TreeSet类型。
假设我有 a Type awhich is a java.util.TreeSet<T>,已通过泛型参数化,由于类型擦除,我们看不到。我们还有Type b一个 'java.lang.Integer'。我如何构造 a ParameterizedTypethat 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 等工具动态创建。