用反思实施战略模式

时间:2011-09-23 14:45:55

标签: java class reflection classnotfoundexception strategy-pattern

我正在尝试使用反射来实现strategy pattern,即使用它的类名实例化一个新的Concrete Strategy对象。

我想要一个包含类名的可配置文件。我们有一个数据库管理器,可以在运行时进行更改。这是我到目前为止所做的:

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;

我有一个ConcreteStrategy类来实现StrategyInterface。我在whcih 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();

2 个答案:

答案 0 :(得分:2)

您确定不会忘记包名称和类StackStrategy可用于类加载器吗?

答案 1 :(得分:2)

假设您为forName()提供的类名是完全合格且正确的。

ClassNotFoundException就是这个意思。

所以你需要确保ConcreteStrategy.class(或包含它的jar文件)在类路径中。

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

两者兼得后,您可以使用URLClassLoader从ConcreteStrategy.class文件或jar_with_ConcreteStrategy_class.jar创建ConcreteStrategy实例。

URLClassLoader example.