簡體   English   中英

在Java上動態調用方法

[英]Invoke Methods Dynamically on Java

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

我正在嘗試創建的是一個動態表格來生成報告。 我首先想到的是創建一個簡單的框架,其中包含列為復選框的列的列表,並且用戶可以選擇他想要的列(當然,還有一個全選按鈕和另一個全選按鈕)。

由於所有列的名稱都與TO類的屬性相同,因此我開發了以下代碼(我使用Google編寫):

Class c = Test.class;

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

這是做我需要的更好的方法嗎?

提前致謝。

觀察:TO類的獲取器的模式為“ getAttribute_Name”。

注意:此問題與用戶要求HOW調用某些給定名稱的方法的問題不同。 我知道該怎么做。 我要問的是這是否是解決我所描述問題的更好方法。

我的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的行為,但是重復執行至少可以確保您不會因意外調用不相關的吸氣劑而煩惱。

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

您可以通過Java Beans, 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));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM