1

我猜我绝对不可能做类似的事情:

Class c = Class.forName("Processor<Integer, String>");

在 Java 中?(当然,我之前定义了处理器)。

4

2 回答 2

2

绝对不可能,因为泛型参数只能在编译时存在。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 实例。正如我所说,没有办法在运行时创建泛型实例,因为泛型只存在于编译时。

于 2012-09-21T20:08:28.127 回答
0

首先让我理顺一些事情。ClassJava 中没有用于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);
于 2012-09-22T23:05:35.850 回答