使用循环设置Bean的属性

时间:2015-07-30 13:27:30

标签: java performance for-loop reflection javabeans

我有一个名为Bean的类,它有3个字段

public class Bean {

private Object field0;
private Object field1;
private Object field2;

public Object getField0() {
    return field0;
}

public void setField0(Object field0) {
    this.field0 = field0;
}

public Object getField1() {
    return field1;
}

public void setField1(Object field1) {
    this.field1 = field1;
}

public Object getField2() {
    return field2;
}

public void setField2(Object field2) {
    this.field2 = field2;
}

我想用数据设置每个字段

    int j, i;

    for (j = 0; j < body.size(); j++) {
        line = new Bean();
        List row = body.get(j);

        HashMap map = new HashMap(headers.length);

        for (i = 0; i < headers.length; i++) {

            line.choosefield2(i, headers, row);
        }
        list.add(line);
    }

和choosefield2在bean中:

public void choosefield2(int i, String[] headers, List row) {

    switch (i) {

    case 0:
        this.setField0(row.get(0));
        break;

    case 1:
        this.setField1(row.get(1));
        break;

    case 2:
        this.setField2(row.get(2));
        break;

我可以在for循环中执行此操作而不是进行大小写切换吗?我有三个以上的领域,所以它不太实际。我听说反射可能是一种选择。我想要像

这样的东西
for (i = 0; i < headers.length; i++) {
        line.setField[i]=row.get(i);
        }
        list.add(line);
    }
这可能吗?使用JDK 1.6

3 个答案:

答案 0 :(得分:2)

你可以,问题是,如果你应该。当然,您可以动态搜索方法并通过反射调用它们。

Class<?> clz = Bean.class;
Method[] methods = clz.getDeclaredMethods();
// etc.
methods[i].invoke( ... );

但这并不能帮助您使代码更具可读性 - 而且会降低您的应用程序速度。此外,您当然会失去很多类型安全性和编译器检查,可能会在运行时发生异常时替换许多编译器错误。只有在没有其他选择时才应该这样做。

答案 1 :(得分:2)

Apache commons-beanutils是一个创建的项目,它比使用原始反射更容易处理bean。你可以这样做:

RequestForResource

请注意BeanUtils,因为我似乎记得它认为getClass()是一个属性,因为它看起来像一个getter。您可能想要检查BeanUtils找到的每个属性的setter。

答案 2 :(得分:2)

这听起来像是Java 8的理想任务:

// keep and reuse this list:
List<BiConsumer<Bean,Object>> setters=Arrays.asList(
  Bean::setField0, Bean::setField1, Bean::setField2);

Bean bean;
List<Object> values;

assert setters.size()==values.size();
for(int i=0, num=setters.size(); i<num; i++)
    setters.get(i).accept(bean, values.get(i));

此代码不使用Reflection,而是使用已定义属性的显式列表,因此您将在编译时注意到错误。但添加新属性仍然比在开头添加Bean::setNewProperty一样简单......

所有豆子的构造可能如下所示:

List<List<?>> body;

List<Bean> beans=body.stream().map(row-> {
    Bean bean=new Bean();
    for(int i=0, num=setters.size(); i<num; i++)
        setters.get(i).accept(bean, row.get(i));
    return bean;
}).collect(Collectors.toList());