使用类对象作为类型

时间:2018-08-07 00:03:30

标签: java inheritance reflection

我的班级层次结构如下:

  • PersistedObject(无法修改或扩展
    • Foo
    • 酒吧
    • 巴兹

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

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

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

因此,我想从FooBarBaz删除所有这些样板。理想情况下,我会明白这一点:

  • PersistedObject(无法修改或扩展此对象)
    • CustomPersistedObject
      • Foo
      • 酒吧
      • 巴兹

也就是说,我想实现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;
}

2 个答案:

答案 0 :(得分:2)

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

所有这些都清楚地记录在Javadoc中。

答案 1 :(得分:0)

  

但是,事情是copy()方法的第一行   要求我使用具体类型来缓存对象的状态   自FooBarBaz开始复制前,每个人都将自己的不同字段添加到   PersistedObject

在那儿等一下。您似乎有一个误解。您之前说过您通过超类获得copyPersistedObject ,因此它是超类的实例方法或静态方法 。在这种情况下,变量copy的声明类型与copyPersistedObject()的行为无关。在每种情况下都将选择相同的实现,并且该实现显然可以对FooBarBaz类型的参数进行正确的处理。 该实现看不到调用方如何声明其自变量。

由于您要将this传递给该方法,因此我认为它是静态的。您似乎希望您的copy()方法是一个实例方法,但是从您呈现的内容来看,似乎您已经使用的几乎相同的模式适用于所有Foo,{{ 1}},如果在Bar上实现一次 ,则Baz,如下所示:

CustomPersistedObject

一种方法可能与现有的三种方法不同的唯一方法是,如果class CustomPersistedObject extends PersistedObject { // ... protected PersistedObject copy() { CustomPersistedObject copy = toBuilder().build(); copy.copyPersistedObject(this); return copy; } // ... } 实际上在每个子类上是不同的静态方法,则与您所描述的相反。

  

所以,我有点想把自己的头缠在反射上,以达到这个目的   完成后,有什么方法可以让我在其中获取Java对象的copyPersistedObject()   运行时,然后将其用作实例化类型本身?

您可以使用.class对象实例化相应类型的实例。您可以从Javadocs中学习类ClassnewInstance()的{​​{1}}方法的更多信息,但这确实是在树错了方向。 >