【问题标题】:Use Class Object as Type使用类对象作为类型
【发布时间】:2018-08-07 00:03:30
【问题描述】:

我的类层次结构如下:

  • PersistedObject(不能修改或扩展这个)
    • 酒吧
    • 巴兹

其中FooBarBaz 是扩展 PersistedObject 的类。但是有代码味道,FooBarBaz 都有一个对象复制的实现,每个类中基本相同,没有类型文字:

protected PersistedObject copy() {
    Foo copy = toBuilder().build();
    copy.copyPersistedObject(this);
    return copy;
}

我通过超类获得copyPersistedObject,它实现了与数据库持久性相关的逻辑。

所以我想从FooBarBaz 中删除所有这些样板。理想情况下,我会做到这一点:

  • PersistedObject(不能修改或扩展它)
    • CustomPersistedObject
      • 酒吧
      • 巴兹

也就是说,我想实现 copy() 的单个实现,并使其 FooBarBaz 都扩展自我的 CustomPersistedObject 类。

不过,copy() 方法的第一行要求我使用具体类型来缓存对象预复制的状态,因为 FooBarBaz 分别添加自己的不同字段到PersistedObject,然后执行copyPersistedObject()处理数据库的东西,最后返回我在copyPersistedObject调用后捕获的状态。

所以,我有点想用反射来完成这项工作,有什么方法可以在运行时获取 java 对象的.class,然后将其用作类型本身来实例化?

我想达到这样的目的:

protected PersistedObject copy() {
    Class<?> clazz = this.getClass();
    [clazz.asType] copy = toBuilder().build();
    copy.copyPersistedObject(this);
    return copy;
}

【问题讨论】:

  • 你能让PersistedObject 通用吗?你能把Class 传递给copy 吗?
  • 如果PersistedObject不能被修改或扩展,那它怎么能有CustomPersistedObject作为子类呢?您是否可能需要删除“或扩展”部分?
  • 我的措辞不好,我不能修改它,但我可以从它扩展到一个新的子类。

标签: java inheritance reflection


【解决方案1】:

一旦您获得Class 对象,您就可以反思性地找到构造函数,选择合适的构造函数,然后调用Constructor#newInstance(...) 方法。

这一切都清楚地记录在 Javadoc 中。

【讨论】:

    【解决方案2】:

    不过,copy() 方法的第一行 要求我使用具体类型来缓存对象的状态 由于FooBarBaz 的预复制,每个都将自己不同的字段添加到 PersistedObject,

    请稍等。你好像有什么误解。你之前说过你通过超类得到copyPersistedObject,所以它要么是实例方法,要么是超类的静态方法。在这种情况下,变量copy 的声明类型与copyPersistedObject() 的行为无关。在每种情况下都将选择相同的实现,并且该实现显然可以使用FooBarBaz 中的任何类型的参数做正确的事情。 该实现看不到调用者如何声明其参数。

    由于您将 this 传递给该方法,我认为它是静态的。您似乎希望您的 copy() 方法成为实例方法,但从您所提供的内容来看,您已经使用的几乎相同的模式似乎适用于所有 FooBar 和 @ 987654336@ 如果在CustomPersistedObject 上实施一次,如下所示:

    class CustomPersistedObject extends PersistedObject {
    
    // ...
    
    protected PersistedObject copy() {
        CustomPersistedObject copy = toBuilder().build();
    
        copy.copyPersistedObject(this);
        return copy;
    }
    
    // ...
    
    }
    

    如果copyPersistedObject() 实际上是每个子类上的不同静态方法,则一种方法可能与您的三个现有方法不同的唯一方法,与您所描述的相反。

    所以,我有点想通过反射来获得这个 完成了,有什么方法可以让我得到一个java对象的.class 运行时,然后将其作为类型本身来实例化?

    您可以使用Class 对象来实例化相应类型的实例。您可以从 Javadocs 中了解更多关于 ClassConstructor 类的 newInstance() 方法的信息,但这似乎真的是找错了方向。

    【讨论】:

    • 有趣的是,copyPersistedObject() 确实来自超类,因此,它不是在每个 DTO 上实现不同的方法。但是 copyPersistedObject 不是静态的。另外,如果我要在 CustomPersistedObject 类型的对象上调用构造函数 .build(),我认为这可能会让我从对象中删除信息,因为我想保留从 DTO 类型获得的所有新信息, FooBarBaz。然而,这种帮助我从另一个角度看待问题。我想我现在需要研究一下 javadoc。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 2012-05-29
    • 2021-02-27
    • 1970-01-01
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多