Reflection API用于在基类的实例化或来自不同项目的扩展版本之间进行选择

时间:2016-02-26 10:48:50

标签: java oop reflection

我们假设Human中有一个名为ProjectA的班级。它在同一项目的CreatureBuilder类中实例化。

现在我想在另一个项目中创建一个名为Cyborg的新类,即ProjectBProjectB在其导入中有ProjectA,但ProjectAProjectB一无所知。

Cyborg extends Human,并且还必须由CreatureBuilder的{​​{1}}实例化(因此,ProjectA位于Cyborg,我致电ProjectBCreatureBuilder到实例化ProjectB,但Cyborg位于CreatureBuilder,以及我的ProjectA类。

我需要一个逻辑来在HumanHuman实例化时创建CreatureBuilder,并在ProjectA从{Cyborg实例化时创建CreatureBuilder 1}}。

我知道可以通过使用ProjectB方法(将在getCreature()中重写)和工厂类创建接口来完成。 但我可以使用Reflection API吗?从它的描述来看,它看起来像是为了做一些相关的事情(如果我错了,请纠正我)。我知道反射很慢,我通常会避开它们。但出于好奇心,看到概念验证会很棒。

2 个答案:

答案 0 :(得分:0)

听起来你想使用泛型

public class CreatureBuilder<T extends Creature> {
    private Class<T> type;

    public CreatureBuilder<T>(Class<T> type) {
        this.type = type;
    }

    public T build() {
        return type.newInstance();
    }
}

CreatureBuilder<Human> humanBuilder = new CreatureBuilder<>(Human.class);            

答案 1 :(得分:0)

如果您预定义Class.forName()的完全限定名称,则可以使用HumanFactory执行此操作。

假设此HumanFactory必须具有此完全限定名称:com.mycompany.HumanFactory

  • 项目A可以尝试在其类路径中找到此类。
  • 如果找到它,请将其实例化并使用它来实例化Human。
  • 如果找不到,请实例化默认的Human类。

在项目A中:

首先,声明HumanFactory

的界面
public interface HumanFactoryItf() {
   Human newHuman();
}

然后,这是CreatureBuilder

的存根
public class CreatureBuilder {

  public Human build() {
    try {
      HumanFactoryItf factory = 
        (HumanFactoryItf)Class.forName("com.mycompany.HumanFactory").newInstance();
      return factory.newHuman();
    } catch(ClassNotFoundException e) {
      return new Human();
    }
  }

}

在ProjectB中:

package com.mycompany;

public class HumanFactory implements HumanFactoryItf {

  public Human newHuman() {
    return new Cyborg();
  }

}

来自主要班级:

public static void main(String[] args) {
  CreatureBuidler cb = ...

  /*
   This line : class.forName("com.mycompany.HumanFactory") 
   will end up instantiating the HumanFactory of ProjectB.
   */
  Human h = cb.build();
}

仅供参考,slf4j使用此模式来决定使用哪种记录器实现。