反射嵌套方法调用

时间:2015-09-09 20:18:52

标签: java reflection annotations nested-attributes

我试图定义一个fieldName->方法地图,我可以为多个实例重用它。我的想法是,我只使用一次反射而不是每个实例。

例如,根据下面的客户端类,地图将具有' name'指向与getName()对应的Method对象 - Map<" name",Class.getName()>。然后我可以在Client类的任何实例上调用getName()方法。

如何处理嵌套属性。例如,给定下面的Currency类,我如何获得一个将调用Client.accounts [1] .currency.code的Method对象?

public class Client{

    @Field( value = "name")
    public String getName(){...}

    @Field( value = "accounts" )
    public List<Account> getAccounts(){...}
}

public class Account{

    @Field( value = "acctNum")
    public Long getAcctNum(){...}

    @Field( value = "currency" )
    public Currency getCurrency(){...}
}

public class Currency{
    @Field( value = "code" )
    public String getCode(){...}
}

首先,我要创建一个fieldName到Method的地图。我打算只做一次,然后重用对象实例。

Map<String, Method> fieldMap = new HashMap();
for( Method method : Client.class.getDeclaredMethods() ){
    Annotation annotation = method.getAnnotation(com.acme.Field.class);
    if( annotation == null) {
        continue;
    }

    com.acme.Field fieldMapping = (com.acme.mapping.Field) annotation;
    String fieldName = fieldMapping.value();
    fieldMap.put(fieldName, method);
}

以下是我计划如何重复使用

Client client = new Client();
for( Map.Entry<String, Method> entry : fieldMap.entrySet() ){
    System.out.println(entry.getKey()+" -> "+entry.getValue().invoke(client, null));
}

1 个答案:

答案 0 :(得分:0)

为此,apache bean utils非常有用。因为它是最受欢迎的java库之一。

但对于小型项目,我使用自编写的实用程序https://bitbucket.org/cache-kz/reflect4j/overview

它支持POJO样式的对象,带有公共字段。 例如:

public class A {
  public int a;
  public int b;
}

或Java Bean样式的对象,带有getter和setter。 例如:

public class A {
  protected int a;
  protected int b;

  public int getA() {
    return a;
  }
  public void setA(int a) {
    this.a = a;
  }
  public int getB(){ ... }
  public void setB(int b) { ... }
}

也支持混合对象。

对于您的示例代码将很简单:

import kz.cache.reflect4j.ObjectManager
ObjectManager manag = new ObjectManager();
Object currencyCode = reader.getValue("accounts[1].currency.code", instanceOfClient);

其他示例可以在测试包中找到: https://bitbucket.org/cache-kz/reflect4j/src/c344d76a4896235f6a1b09b2499d5ae25adc2900/src/test/java/kz/cache/reflect4j/ObjectManagerTest.java