【问题标题】:Create instance of Generic class at runtime with getConstructor(): NoSuchMethodException()在运行时使用 getConstructor() 创建 Generic 类的实例:NoSuchMethodException()
【发布时间】:2014-10-08 02:10:27
【问题描述】:

我正在使用泛型并且需要在运行时创建一个泛型类的实例,所以我尝试使用 getConstructor()。不幸的是,尽管签名正确,我还是收到了 NoSuchMethodException,所以我不知道出了什么问题。我会很感激你的建议,这样我就可以解决这个问题。 :) 我已经为 CustomerAssembler 提供了构造函数。由于使用了泛型,我需要动态地创建这个类的一个实例。我已经包含了我正在使用的代码的 sn-p。在其中,我调用了 getConstructors() 来查看构造函数是否存在以及它们的签名。两个构造函数都存在并且我使用了正确的签名,所以我不知道为什么我不断收到这个异常。 Arggg ...希望你会看到我做错了什么。 :)

感谢您的时间和帮助, 迈克

 // Here are the constructors for CustomerAssembler.

    public CustomerAssembler()
    {
        super();
    }   

    public CustomerAssembler(
            Class<Customer> entityClass, 
            Class<CustomerPreviewDTO> entityPreviewDTOClass, 
            Class<CustomerDetailDTO> entityDetailDTOClass,
            Class<CustomerUpdateDTO> entityUpdateDTOClass,
            EntityManager entityManager)
    {
        super(entityClass, entityPreviewDTOClass, entityDetailDTOClass, entityUpdateDTOClass, entityManager);
    }

这里是例外:NoSuchMethodException:

java.lang.NoSuchMethodException: assemblers.CustomerAssembler.<init>(entities.Customer, dtos.CustomerPreviewDTO, dtos.CustomerDetailDTO, dtos.CustomerUpdateDTO, javax.persistence.EntityManager)

这里是代码...

    try
    {
        Class<CustomerAssembler> customerAssemblerClass = CustomerAssembler.class;

        Constructor<CustomerAssembler>[] lst = (Constructor<CustomerAssembler>[]) this.customerAssemblerClass.getConstructors();

/* See what the signature is for the non-default constructor, so I can make sure that
           getConstructor() is configured properly.  Here is what was reported in the debugger:

           [0] = {java.lang.reflect.Constructor@10796}"public assemblers.CustomerAssembler()"

           [1] = {java.lang.reflect.Constructor@10797}"public assemblers.CustomerAssembler(java.lang.Class,java.lang.Class,java.lang.Class,java.lang.Class,javax.persistence.EntityManager)"
     signature = {java.lang.String@10802}"(Ljava/lang/Class<Lentities/Customer;>
                                                   Ljava/lang/Class<dtos/CustomerPreviewDTO;>
                                                   Ljava/lang/Class<dtos/CustomerDetailDTO;>
                                                   Ljava/lang/Class<dtos/CustomerUpdateDTO;>
                                                   Ljavax/persistence/EntityManager;)V"
        */

        // Configure our constructor call...  this.contactAssemblerClass
        Constructor<CustomerAssembler> ca =
                customerAssemblerClass.getConstructor(
                        Customer.class,
                        CustomerPreviewDTO.class,
                        CustomerDetailDTO.class,
                        CustomerUpdateDTO.class,
                        EntityManager.class);

    // Create an instance here...

    }
    catch (NoSuchMethodException e)
    {
        e.printStackTrace();
    }
    catch (InstantiationException e)
    {
        e.printStackTrace();
    }
    catch (IllegalAccessException e)
    {
        e.printStackTrace();
    }
    catch (InvocationTargetException e)
    {
        e.printStackTrace();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

【问题讨论】:

    标签: java generics reflection getconstructor


    【解决方案1】:
    customerAssemblerClass.getConstructor(
                        Customer.class,
                        CustomerPreviewDTO.class,
                        CustomerDetailDTO.class,
                        CustomerUpdateDTO.class,
                        EntityManager.class);
    

    这会查找具有以下签名的构造函数:

    CustomerAssemble(Customer c,
                     CustomerPreviewDTO cpDTO, 
                     CustomerDetailDTO cdDTO, 
                     CustomerUpdateDTO cuDTO, 
                     EntityManager em)
    

    您的构造函数不会将其作为参数。它需要 4 个 Class 实例和一个 EntityManager 实例。

    所以代码应该是

    customerAssemblerClass.getConstructor(
                        Class.class,
                        Class.class,
                        Class.class,
                        Class.class,
                        EntityManager.class);
    

    【讨论】:

    • 啊!谢谢,JB!我应该从异常消息中意识到我的错误!我已将代码更改为您推荐的签名,现在它找到了构造函数! :) 我不确定是否适合在进行此更改后提出后续问题,或者是否应该打开一个新问题...我会问,但如果不合适,请告诉我,我将打开一个新的。得到构造函数后,我需要创建一个实例,所以我做了以下,但是失败了一个 IllegalArgumentException: argument type mismatch.
    • 我正在传递所需的课程,所以我不确定出了什么问题。我会很感激你的cmets。再次感谢您的回复! this.contactAssembler = ca.newInstance(Customer.class, CustomerPreviewDTO.class, CustomerDetailDTO.class, CustomerUpdateDTO.class, EntityManager.class);
    • 您的构造函数将 4 个类作为参数:Customer.class、CustomerPreviewDTO.class、CustomerDetailDTO.class、CustomerUpdateDTO.class。但最后一个参数不是一个类。它是 EntityManager 的 instance
    • 非常感谢您,JB!我进行了更改,代码工作正常。我学到了很多东西,我希望这篇文章也能帮助其他人。有一个美好的夜晚! :)
    猜你喜欢
    • 1970-01-01
    • 2014-03-08
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-05
    相关资源
    最近更新 更多