繁体   English   中英

从类文件实例化通用参数化类型

[英]Instantiating Generic Parameterized Type from class file

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

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

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

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

    //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>行中给了我很多错误,所以我认为这不是正确的方法。 我究竟做错了什么?

Tere这里有几个问题...

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

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

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

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

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

     if (B.isAssignableFrom(A)) { // ... } 
  • 为了避免警告-对不起,这种类型转换真的是不加以控制,因为没有办法,以确保它的正确性在运行时-再次,由于输入erasuer。 在您知道@SuppressWarnings有效且Java类型系统太笨而无法验证您的声明的地方使用@SuppressWarnings

无论如何,不​​要上课。 相反, newInstance调用的结果。 现在,关于运行正确的方法...现在,您将获得所需的所有信息,分为两部分:调用方法的对象和已实现接口的参数类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM