我猜我绝对不可能做到这样的事情:
Class c = Class.forName("Processor<Integer, String>");
在Java中? (当然,我之前定义过处理器)。
答案 0 :(得分:2)
绝对没办法,因为泛型参数只能在编译时存在。 Class
对象在运行时是相同的。它不是C ++中的类模板。类型参数只是java编译器的信息。
您可以尝试通过创建类来完成类似的事情:
class IntStringProcessor extends Processor<Integer, String> {}
和Class c = Class.forName("IntStringProcessor");
在运行时,您可以通过Processor
获取实际的c.getGenericSuperclass()
类型参数,但这扩展了我猜的问题。
编辑:另一个想法
您的Processor
可能会将classess作为参数保留,然后:
Class c1 = Class.forName("java.lang.Integer");
Class c2 = Class.forName("java.lang.String");
Processor = new Processor(c1,c2);
您的处理器现在不是通用的,但在内部使用Class实例。正如我所说,没有办法在运行时创建通用实例,因为泛型仅在编译时存在。
答案 1 :(得分:0)
首先让我理顺一些事情。 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
,则可能需要使用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 pattern。只需在new GenericType<...>() {}
内添加所需的任何类型名称:
type = typeResolver.resolve(new GenericType<Processor<Processor<Integer, String>, Character>>() {});
System.out.println("type = " + type);