【问题标题】:Instantiate Object from Class从类实例化对象
【发布时间】:2015-12-30 14:49:21
【问题描述】:

我目前正在编写一个库,用户可以在其中创建父抽象类Module 的自己的子类。 所以这个库已经包含了我写的一些模块,例如ModuleOne, ModuleTwo, ...

每个Module - 子类都应该可以通过唯一标识符轻松识别,例如整数,因为我想将多个模块配置和连接保存在一个 xml 文件中。 所以我可以稍后加载保存的配置并实例化所需类型的对象。

如果我只使用预定义的类,这很容易,因为我知道ModuleOneModuleTwo 的标识符,所以我可以在函数中创建模块:

public static Module getModuleByType(int type)
{
     if (type == ModuleOne.TYPE)
         return new ModuleOne();
     else if (type == ModuleTwo.TYPE)
         return new ModuleTwo();
     //and so on...
}

但是如果用户创建了Module 的子类,例如CustomModule,我该如何为这个类分配唯一的标识符,使这个类的所有实例都具有相同的类型标识符?

如何根据它们的标识符动态重新创建这些模块?所以我无法在getModuleByType() 中创建模块,因为我不知道它们的构造函数和标识符。

感谢您的帮助。

【问题讨论】:

  • 如果你不知道它们的构造函数,你永远无法实例化它们,因为你不知道它们的构造函数的参数是什么意思。
  • 听起来你正在重新创建 Spring IOC。

标签: java


【解决方案1】:

我不认为这是一个好的设计。如何确保子类不重用已使用的类型?如果有人已经有了自己的带有唯一标识符的子类,然后导入另一个库并发现他们有重复的标识符怎么办?您的设计容易出现几个错误。

一般来说,您不可能做这样的事情,因为子类可能与其父类有很大不同。

如果你不知道它们的构造函数,你永远无法实例化它们,因为你不知道它们的构造函数的参数是什么意思。

一个相对有用的解决方案是“强制”子类有一个特定的构造函数,比如说无参数构造函数,那么你可以这样做:

public static Module getModuleByType(final Class<? extends Module> moduleSubClass) {
    Constructor<? extends Module> ctor = moduleSubClass.getConstructor();
    return ctor.newInstance();
}

虽然这比直接执行 new ModuleSubClass() 慢,但您会强制所有子类具有无参数构造函数。

【讨论】:

    【解决方案2】:

    您可以使用完整的类名(带有包)作为标识符并使​​用它重新创建它

    Class<?> clazz = Class.forName(className);
    Module module = (Module)clazz.newInstance();
    

    【讨论】:

    • @m0skit0 此对象将从xml 重新创建,因此它必须具有默认构造函数。
    • 这毫无意义。就像在说:太阳是黄色的,所以西红柿是红色的。
    • @m0skit0 当我们通过 JAXB 从 XML 创建 POJO 时……所有这些 POJO 类都有默认构造函数。所有数据都可以由setter指定。
    • OP 在哪里指定他正在使用 JAXB?
    • @m0skit0 无处,当然,这是一个模拟。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 2016-06-13
    相关资源
    最近更新 更多