2016-04-30 59 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)); 
}