【问题标题】:Java - Create new Instance using Reflection without knowing constructor paramsJava - 在不知道构造函数参数的情况下使用反射创建新实例
【发布时间】:2012-12-08 04:03:14
【问题描述】:

我需要创建许多类的新实例。我正在使用反射,但是当我创建 c.newInstance() 时,没有“空参数构造函数”的类会抛出 java.lang.InstantiationException。

现在,我该如何创建每个类的实例?

我知道我可以使用 c.getConstructor(Class).newinstance(params) 创建没有“空参数构造函数”的类的实例,但我不知道每个类的参数。

还有一件事,所有这些类都是从另一个名为 ParentClass 的类扩展而来的,所以我可以使用的一种解决方法是在 ParentClass 中包含一些代码,强制子类实现“空参数构造函数”,但不要知道该怎么做。

提前致谢!

【问题讨论】:

  • 大多数依赖反射来创建对象的主要框架都有一个规则,即一切都必须有一个无参数构造函数,在代码中不会以任何方式“强制”,你只需要知道你必须包括它。

标签: java reflection


【解决方案1】:

您可以调用Class.getConstructors() 来获取给定类的所有构造函数。

在每个Constructor 上,您可以调用Constructor.getGenericParameterTypes() 以了解它需要哪些参数。

【讨论】:

    【解决方案2】:

    你不能。没有办法“要求”无参数构造函数并由编译器强制执行,并且根据定义,要创建类的实例,您必须为其提供必要的参数,否则您将得到一个违反类契约(因为它没有正确初始化)。

    在代码级别强制执行此操作的正确方法是使用对象工厂和接口。我假设您必须使用反射,因为您在编译时不知道类型;在这种情况下,还应该有一个“工厂”,它知道如何生成每种类型的实例。该工厂应该使用相关类型构建/编译,以便它知道并可以调用正确的构造函数。然后,工厂实现您的代码知道的接口,例如“ObjectFactory”,它允许您委托给工厂以实例化对象。然后,您将拥有一些方法,对象工厂可以使用该方法注册为负责它可以实例化的任何类型。

    在您尝试创建的类附带的代码中:

    static {
        FactoryRegistry.register(TypeA.class, new TypeAFactory());
    }
    

    在你的代码中:

    Class<?> unknownClass = ...;
    Object obj = FactoryRegistry.getFactory(unknownClass).newInstance();
    

    (您有一个TypeAFactory 实现并指定newInstance 方法的Factory 接口)

    您不知道unknownClass 是什么或如何实例化它,但是如果该类附带的代码注册了一个工厂,您可以查询该工厂并​​要求它为您创建对象。如果unknownClass 真的是TypeA.class,那么注册中心将返回为创建对象而注册的TypeAFactory


    或者,您可以只要求您的框架动态加载的任何代码的作者都包含一个无参数的构造函数。它不是严格执行的,但作者可以更容易地实施。

    【讨论】:

      【解决方案3】:

      创建类实例的反射方法有两种java.lang.reflect.Constructor.newInstance()Class.newInstance()

      Class.newInstance() 只能调用零参数构造函数,而

      Constructor.newInstance() 可以调用任何构造函数,而不管参数的数量是多少

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-05
        • 2011-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多