从Java对象动态选择字段

时间:2012-10-14 09:20:52

标签: java database select enums

我在Java中有一个表示数据库内容的Object,如下所示:

public Database {
    int varA;
    String varB;
    double varC;
}

现在我正在尝试选择和订购某些元素以进行更深入的处理,但我想让它可配置,所以我创建了一个枚举,表示对象的所有属性,如

public enum Contents {
    VarA,
    VarB,
    VarC;
}

所以现在当我创建一个像

这样的选择时
Contents[] select = { Contents.VarC, Contents.VarB };

我想生成一个String值列表,表示实际的数据库内容。现在,我能想到的唯一一个实现是切换选择中的每个条目,具有非常丑陋的二次复杂度......

public List<String> switchIT(Database db, Contents[] select) {
    List<String> results = new ArrayList<String>();

    for (Contents s : select) {
        switch(s) {
            case VarA:
                results.add(db.varA.toString());
                break;
            //go on...
        }
    }

    return results;
}

有更直接的方法在枚举和动态对象值之间进行映射吗? 或者用更一般的术语:动态选择对象值的最佳方法是什么?

1 个答案:

答案 0 :(得分:3)

使用Java枚举的强大功能,这是完全成熟的类。

public enum Contents {
  VarA { public String get(Database d) { return d.getVarA(); } },
  VarB { public String get(Database d) { return d.getVarB(); } },
  VarC { public String get(Database d) { return d.getVarC(); } };
  public String get(Database d) { return ""; }
}

您的客户端代码将变为

public List<String> switchIT(Database db, Contents[] select) {
  List<String> results = new ArrayList<String>();
  for (Contents s : select) results.add(s.get(db));
  return results;
}

更简洁但更慢的解决方案是基于反射使用get的单个实现,并使用枚举成员的名称生成相应的getter名称:

public enum Contents {      
  VarA, VarB, VarC;

  private final Method getter;

  private Contents() {
    try {
      this.getter = Database.class.getMethod("get"+name());
    } catch (Exception e) { throw new RuntimeException(e); }
  }
  public String get(Database d) {
    try {
      return (String) getter.invoke(d); 
    } catch (Exception e) { throw new RuntimeException(e); }
  }
}