【问题标题】:Implementing Strategy pattern with Reflection使用反射实现策略模式
【发布时间】:2011-11-23 18:09:28
【问题描述】:

我正在尝试使用反射实现strategy pattern,即使用它的类名实例化一个新的具体策略对象。

我想要一个包含类名的可配置文件。我们有一个数据库管理器,它将在运行时提供更改。这是我目前所拥有的:

StrategyInterface intrf = null;
try {
    String className = (String)table.get(someId);
    intrf = (StrategyInterface) Class.forName(className).newInstance();
} catch (InstantiationException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    System.out.println(e.getMessage());
}
return intrf;

我有一个实现StrategyInterface 的类ConcreteStrategy。我有一个测试正在运行,table.get(someID) 返回String "ConcreteStrategy"

我的问题是ClassNotFoundEception 被抛出。为什么会发生这种情况,以及如何让ConcreteStrategy 在给定类名的情况下被实例化?我不想使用if-else 块,因为具体策略对象的数量会随着时间和发展而增加。

编辑:我通过以下方式修复了它,

String className = (String)table.get(custId);
className = TrackingLimiter.class.getPackage().getName() + "." + className;
limiter = (TrackingLimiter) Class.forName(className).newInstance();

【问题讨论】:

  • ConcreteStrategy 是否包含在您的类路径中?您是否在 forName() 调用中使用了类的 FQN(包 + 名称)?
  • 发布您如何填充“表格”战略地图。
  • 谢谢,成功了。我的印象是它会自动添加包名。但是添加包名是有效的。

标签: java class reflection classnotfoundexception strategy-pattern


【解决方案1】:

你确定你没有忘记包名和类 ConcreteStrategy 可用于类加载器吗?

【讨论】:

    【解决方案2】:

    假设您提供给 forName() 的类名是完全限定且正确的。

    ClassNotFoundException 就是这个意思。

    因此您需要确保ConcreteStrategy.class(或包含它的 jar 文件)在类路径中。

    如果新类真正动态可用,即您知道当您的程序启动时,ConcreteStrategy.class 不存在,但几小时/几天后有人实现了它并将完全限定的类名放入 DB 表中,那么除了类名之外,您还需要资源名称(ConcreteStrategy.class 的路径(或包含它的 jar 文件))。

    一旦你拥有这两者,你就可以使用 URLClassLoader 从ConcreteStrategy.class 文件或jar_with_ConcreteStrategy_class.jar 创建一个 ConcreteStrategy 的实例。

    URLClassLoader example.

    【讨论】:

    • 非常感谢,这很有帮助,当事情开始变得严重时会牢记在心。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多