我正在尝试使用反射来实现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();
答案 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实例。