2012-01-15 56 views
11

我正在使用Java開發我的第一個真正的項目。儘管我對動態語言有更多的經驗,但我已經開始習慣這門語言了。Java元編程

我有,其行爲類似於下面的一類:

class Single 
{ 
    public void doActionA() {} 
    public void doActionB() {} 
    public void doActionC() {} 
} 

然後,我有一個SingleList類充當這些類(特別是,它是一個2D雪碧庫,並集合了「行動「是各種轉變:旋轉,剪切,縮放等)。我希望能夠做到以下幾點:

class SingleList 
{ 
    public void doActionA() { 
     for (Single s : _innerList) { 
      s.doActionA(); 
     } 
    } 

    ... etc ... 
} 

有沒有辦法簡單地推遲的方法(或方法的一個已知列表)的內部列表中的每個成員?任何方式,而不必具體列出每種方法,然後循環通過每個內部成員,並手動應用它?

爲了讓事情變得更難,這些方法具有不同的參數,但都是返回類型「void」。

+0

我覺得你可以看看Java反射,它允許你在運行時調用的方法。 – Alvin 2012-01-15 07:11:09

+0

但我仍然需要生成SingleList類中的所有方法存根。我正在尋找更多的解決方案,充當全面調用的方法。就像使用PHP或python getattr調用一樣。 – efritz 2012-01-15 07:13:37

+0

哦,你不需要執行,用反射你可以做SingleList.get(「someAttr」),然後反射會爲你調用方法getSomeAttr()。你可以谷歌「org.springframework.beans.BeanUtils」,這是你想要的。如果沒有人讓我感到厭煩,我會在後面寫一個例子作爲正式答案。 – Alvin 2012-01-15 08:02:20

回答

11

不幸的是,Java不會支持在運行時創建類,這是您需要的:SingleList需要使用必要的存根方法自動更新以匹配Single類。

我能想到以下方法這一問題:

  1. 使用Java reflection

    • 優點:
      • 這是現成的Java語言,你可以很容易地找到文檔和示例。
    • 缺點:
      • SingleList類不會與Single類接口的兼容性更好。
      • Java編譯器和任何IDE通常都無法幫助通過反射調用的方法 - 編譯器會捕獲的錯誤通常會轉換爲運行時異常。
      • 根據您的使用情況,您可能還會看到明顯的性能下降。
  2. 使用帶有某種源代碼生成器來自動創建SingleList.java文件一起構建系統。

    • 優點:
      • 一旦你設置它,你不會有任何更多的處理。
    • 缺點:
      • 設置此功能有難度的。
      • 您必須單獨確保SingleList類加載到任何JVM或您的IDE中,實際上與加載的Single類匹配。
  3. 手動解決這一問題 - 創建一個接口(例如SingleInterface)或通過這兩個類的使用應幫助一個抽象基類,因爲任何像樣的IDE會指出未實現的方法。適當的類架構可以最大限度地減少重複的代碼,並且您的IDE可能會幫助生成樣板零件。

    • 優點:
      • 沒有設置曲線克服。
      • 您的IDE將始終看到正確的類集。
      • 之後通常會改進類架構。
    • 缺點:
      • 一切是手動的。
  4. 使用一個字節碼生成庫如JavassistBCEL動態生成/修改即時的SingleList類。

    • 優點:
      • 這種方法是非常強大的,可以節省大量的時間在長遠。
    • 缺點:
      • 使用字節碼生成庫通常瑣碎和爲膽怯。
      • 根據您編寫代碼的方式,您可能也會遇到IDE及其處理動態類的問題。
+0

看起來像手動方法是要走的路。如果我添加更多轉換,我只需確保將界面保持最新。 – efritz 2012-01-15 18:59:22