1

我試圖使用反射實現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(); 
+1

ConcreteStrategy是否包含在類路徑中?您是否在forName()調用中使用了類的FQN(包+名稱)? – pap

+0

發表你如何填充'表'戰略地圖。 – Hyangelo

+0

謝謝,這工作。我感覺它會自動添加包名。但是添加包名稱起作用。 – Monir

回答

2

你確定你不要忘了包名和類ConcreteStrategy可供類加載器?

2

假設您提供給forName()的類名是完全限定且正確的。

ClassNotFoundException意思是這樣的。

因此,您需要確保ConcreteStrategy.class(或包含它的jar文件)在類路徑中。

如果真的動態獲得新類,即您知道當您的程序開始時,ConcreteStrategy.class不存在,但幾個小時/天后某人實現了它並將完全限定的類名放入數據庫表中,然後和類名一起,您還需要資源名稱(路徑ConcreteStrategy.class(或包含它的jar文件))。

一旦你們兩個都有,你可以使用URLClassLoader從ConcreteStrategy.class文件或jar_with_ConcreteStrategy_class.jar創建一個ConcreteStrategy的實例。

URLClassLoader example.

+0

非常感謝你,這是非常有幫助的,當事情開始變得嚴肅時,我們將會記住未來。 – Monir