0

因此,客户端将以下列方式创建一个类:

public class Tester implements Test<Type1, Type2, Type3> {
    @override
    public method1(...)
    ...
}

然后客户端会将.class文件(IE Tester.class)传递给我们。

然后,我们希望实例化客户端的类并根据泛型使用的类型运行他们的方法 1。到目前为止,我有以下代码,但我认为我没有走正确的道路:

    //tempClass = <ClassName>.class
    Type[] genericTypes;
    Type[] genericInterfaces = tempClass.getGenericInterfaces();
    if(genericInterfaces[0] instanceof ParameterizedType){
        genericTypes = ((ParameterizedType)genericInterfaces[0])
                        .getActualTypeArguments();
    }
    Class<Tester<genericTypes[0], genericTypes[1], genericTypes[2]>> classTest
        = ( Class<Tester<genericTypes[0], genericTypes[1], genericTypes[2]>>) tempClass
    Constuctor<...> = ... //get the constructor
    //Create the new instance by calling .newInstance()

但是 eclipse 在 Class> 行中给了我很多错误,所以我认为这不是正确的路径。我究竟做错了什么?

4

1 回答 1

1

这里有几个问题......

首先,两者Classname.class本质上都是静态构造——它甚至被称为文字。因此,不能在运行时提供类型名称,这就是 Eclipse 抱怨您尝试这样做的原因。要获取Class给定类名作为字符串的对象,可以使用Class.forName

Class<?> tempClass = Class.forName("Tester");

(完全限定的名称,没有.class后缀)。

其次,也是如此Tester<Type1, Type2, Type3>。类型参数必须在编译时已知。现在,我不确定你为什么在这个地方需要这个演员表,但我看到了几个可能的原因:

  • 为了确保由 表示的类tempClass确实实现了适当的接口 - 即使它是语法上合法的构造,它也是没有用的。强制转换不能动态检查泛型类型参数,因为它们也是完全编译时的构造——由于类型擦除,它们在运行时不可用。要检查给定Class对象 A 是否是对象 B 表示的类型的子类/实现Class,我们可以使用Class.isAssignableFrom

    if (B.isAssignableFrom(A)) {
        // ...
    }
    
  • 为了避免警告 - 抱歉,这样的转换确实是未经检查的,因为无法确保其在运行时的正确性 - 再次,由于类型擦除器。@SuppressWarnings在您知道强制转换有效且 Java 类型系统太笨而无法验证您的声明的地方使用。

无论如何,不​​要投射课程。相反,转换newInstance调用的结果。现在,至于运行正确的方法......现在您拥有了所需的所有信息,分为两部分:调用方法的对象和已实现接口的类型参数。

于 2013-08-30T10:40:51.827 回答