2016-04-30 83 views
2

在工作中,我們必須爲客戶生成一個報告,該報告在一週內多次更改其參數。 此報告是從我們的數據庫上的單個表生成的。 例如,想象一個有100列的表格,今天我必須生成一個只有5列的報告,但明天我必須生成其中的95個。 考慮到這一點,我創建了一個包含指定表的所有列的TO類,並且我的查詢返回了所有列(SELECT * FROM TABLE)。在Java上動態調用方法

我想創建的是一個動態的窗體來生成報告。 我首先想到的是創建一個簡單的框架,其中列出的列作爲複選框,用戶將選擇他想要的列(當然選擇全部選擇按鈕,而另一個選擇全部取消選擇)。

由於所有的列具有相同的名稱作爲類的屬性,我制定了以下代碼(我有谷歌這個):

Class c = Test.class; 

for(int i = 0; i < listOfAttributes.length; i++) 
{ 
    auxText += String.valueOf(c.getMethod("get" + listOfAttributes[i]).invoke(this, null)); 
} 

這是更好的方式做我需要至?

在此先感謝。

Obs .: TO類的getters具有模式「getAttribute_Name」。

注意:此問題與用戶詢問如何調用給定某個名稱的某種方法的問題不同。我知道該怎麼做。我問的是,如果這是解決我所描述的問題的更好方法。

+1

的可能的複製[如何調用Java方法當給方法名稱作爲字符串?](http://stackoverflow.com/questions/160970/how-do-i-invoke-a-java-method-when-given-the-method-name-as-a -string) –

+0

就像我在說明中所說:這個問題與用戶詢問如何調用給定某個名稱的某種方法的問題不同。我知道該怎麼做。我問的是,如果這是解決我所描述的問題的更好方法。 –

+0

好的。我會回來的。我會注意到你的筆記是在我第一次審查後添加的。 –

回答

0

我的Java稍微有點侷限,但我相信這和使用反射一樣好。

Class<?> c = Test.class; 

for (String attribute : listOfAttributes) { 
    auxText += String.valueOf(c.getMethod("get" + attribute).invoke(this, null)); 
} 

但由於這聽起來像它可能不受信任的數據是,我會建議使用在這種情況下HashMap,每個方法顯式引用。首先,它明確指出可以動態調用哪些方法。其次,它更安全,編譯時錯誤比運行時錯誤更好。第三,它可能更快,因爲它完全避免了反思。東西這樣的效果:

private static final HashMap<String, Supplier<Object>> methods = new HashMap<>(); 

// Initialize all the methods. 
static { 
    methods.set("Foo", Test::getFoo); 
    methods.set("Bar", Test::getBar); 
    // etc. 
} 

private String invokeGetter(String name) { 
    if (methods.containsKey(name)) { 
     return String.valueOf(methods.get(name).get()); 
    } else { 
     throw new NoSuchMethodException(); 
    } 
} 

這聽起來像一個大DRY違反這樣做,但重複至少可以確保您不無關係干將不慎被稱爲風。

0
Class c = Test.class; 
for(int i = 0; i < listOfAttributes.length; i++) 
{ 
    auxText += String.valueOf(c.getMethod("get" + listOfAttributes[i]).invoke(this, null)); 
} 

您可以通過Java組件某種程度上更優雅爲此,IntrospectorPropertyDescriptor,但它是一個多一點囉嗦:

Map<String, Method> methods = new HashMap<>(); 
Class c = this.getClass(); // surely? 
for (PropertyDescriptor pd : Introspector.getBeanInfo(c).getPropertyDescriptors()) 
{ 
    map.put(pd.getName(), pd.getReadMethod(); 
} 
// 
for (int i = 0; i < listOfAttributes.length; i++) 
{ 
    Method m = methods.get(listOfAttributes[i]); 
    if (m == null) 
     continue; 
    auxText += String.valueOf(m.invoke(this, null)); 
}