我猜我绝对不可能做类似的事情:
Class c = Class.forName("Processor<Integer, String>");
在 Java 中?(当然,我之前定义了处理器)。
我猜我绝对不可能做类似的事情:
Class c = Class.forName("Processor<Integer, String>");
在 Java 中?(当然,我之前定义了处理器)。
绝对不可能,因为泛型参数只能在编译时存在。Class
对象在运行时是相同的。它不是 C++ 中的类模板。类型参数只是 java 编译器的信息。
您可以尝试通过创建一个类来完成类似的事情:
class IntStringProcessor extends Processor<Integer, String> {}
和Class c = Class.forName("IntStringProcessor");
在运行时,您可以通过获取实际Processor
类型参数,c.getGenericSuperclass()
但这扩展了我猜想的问题。
编辑:另一个想法
您Processor
可以将类保留为参数,然后:
Class c1 = Class.forName("java.lang.Integer");
Class c2 = Class.forName("java.lang.String");
Processor = new Processor(c1,c2);
您的处理器现在不是通用的,而是在内部使用 Class 实例。正如我所说,没有办法在运行时创建泛型实例,因为泛型只存在于编译时。
首先让我理顺一些事情。Class
Java 中没有用于Processor<Integer, String>
. 只存在一个 Class
对象Processor
,即Processor.class
所有泛型实例共享同一个Class
对象:
Processor<Integer, String> x = new Processor<Integer, String>();
Processor<Character, Byte> y = new Processor<Character, Byte>();
System.out.println(x.getClass() == y.getClass()); // prints true
话虽如此,如果您只需要让泛型类型的令牌传递,您可以使用第三方实现。在这里,我使用Java ClassMate:
TypeResolver typeResolver = new TypeResolver();
// type token for Processor<Integer, String>
ResolvedType type = typeResolver.resolve(Processor.class, Integer.class, String.class);
System.out.println("type = " + type);
如果您从文件中将 Java 类型的名称读取为String
's,您可能希望使用Class.forName()
而不是我的.class
文字。
您必须自己解析<
,>
括号,但这应该很容易,因为这些单个字符在 Java 类型名称中总是意味着相同的东西......
您可以像这样形成嵌套参数:
// type token for Processor<Processor<Integer, String>, Character>
ResolvedType type = typeResolver.resolve(Processor.class,
typeResolver.resolve(Processor.class, Integer.class, String.class),
typeResolver.resolve(Character.class)
);
System.out.println("type = " + type);
如果你想在编译时为你知道的类型创建类型标记,你可以使用所谓的super-type-token 模式。只需将您需要的任何类型名称放入其中new GenericType<...>() {}
:
type = typeResolver.resolve(new GenericType<Processor<Processor<Integer, String>, Character>>() {});
System.out.println("type = " + type);