這可能是一種技術上可行的方法,但像其他海報一樣,我強烈建議您考慮這是否是解決問題的正確方法(並且您已經問過如何實施此解決方案而不是如何解決您的問題原來的問題,所以我不能告訴你,如果你在正確的軌道上或不)。
您是否有興趣選擇性地取決於圖書館,但不強迫您的客戶提供它?根據你的構建系統,這並不難完成。例如,Maven允許您指定一個依賴關係,如<scope>optional</scope>
,它允許您針對它編譯代碼,但不包括它作爲傳遞依賴項。這就是說,確實有可能可以選擇性地依賴某些庫,並且如果它們不可用,則採取替代路線。根據我的經驗,這很容易通過隱藏界面背後的細節來完成。
作爲示例,我有一個ProfilingAdvisor接口,它可以與AspectJ方面一起使用,以剖析我用自定義標註標記的方法。我有一個名爲SimpleProfilingAdvisor的接口的基本實現,它沒有外部依賴關係。我有一個更詳細的實現,它使用Java Simon庫來獲取更多信息,稱爲SimonProfilingAdvisor。
如果客戶選擇包含Java Simon庫,他們會得到「更好」的實現。如果他們選擇不這樣做,那麼將實施「基礎」方法(在你的情況下可能是什麼都不做)。
我的代碼總是工作到接口,ProfilingAdvisor,但實例化這種類型的實例變量的時候,我必須確定可選西蒙庫是否在類路徑:
private ProfilingAdvisor advisor;
/* ... */
try {
Class.forName("org.javasimon.SimonManager");
this.advisor = new SimonProfilingAdvisor();
} catch (ClassNotFoundException classNotFoundException) {
this.advisor = new SimpleProfilingAdvisor();
}
的最後一點。雖然你可以用反射來確定一個類的存在,但是我不能想到你在實例化之後通過反射方法訪問它而獲得的任何東西,而且你有效地繞過了編譯器的能力,你在方法名稱上的拼寫等。
至少,你應該使用一個構建系統,它允許你在編譯時編譯一個庫,但不一定包括它在你的發行版中(例如Maven) 。
嘗試的Class.forName(「com.foo.MyClass」)。的newInstance(),捕獲它可能拋出的異常,如果它確實拋出,只是不實例com.foo.MyClass? – mwittrock 2010-08-10 13:44:17
感謝您的回答。我的錯!我認爲Sun Java一旦看到一個不存在的「導入」就會拋出異常。看來它只在到達無效行時才拋出異常。 您可以請您的評論作爲答案,以便我可以接受它。 – Mohsen 2010-08-11 06:55:07