1

I'm trying to define a fieldName->Method map that I can reuse for multiple instances. The idea is that I'll use reflection only once instead of for each instance.

For example, given the Client class below, the Map will have 'name' pointing to a Method object that corresponds to the getName() - Map<"name",Class.getName()>. Then I can invoke the getName() method on any instance of the Client class.

How do I deal with nested properties. For example, given the Currency class below, how do I get a Method object that will call Client.accounts[1].currency.code?

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(){...}
}

First I'm creating a map of fieldName to Method. Something that I plan to do only once, and then reuse for object instances.

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);
}

Here's how I plan to reuse it

Client client = new Client();
for( Map.Entry<String, Method> entry : fieldMap.entrySet() ){
    System.out.println(entry.getKey()+" -> "+entry.getValue().invoke(client, null));
}
user2793390
  • 741
  • 7
  • 29
  • It looks to me like Nested Property Access in Apache BeanUtils: http://stackoverflow.com/questions/2753218/how-to-prevent-npe-when-accessing-a-nested-indexed-property-of-a-bean – rsutormin Sep 10 '15 at 23:04
  • And it works for elements in lists too. Take a look at "2.3 Nested Property Access" here: https://commons.apache.org/proper/commons-beanutils/javadocs/v1.8.3/apidocs/org/apache/commons/beanutils/package-summary.html#standard.nested – rsutormin Sep 10 '15 at 23:06

1 Answers1

0

For this purposes apache bean utils is very useful. Because it is one of the most popular java libraries.

But for small projects I use self written utility https://bitbucket.org/cache-kz/reflect4j/overview

It supports POJO style of objects, with public fields. Ex:

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

Or Java Bean style of objects, with getters and setters. Ex:

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) { ... }
}

Mixed objects supported too.

For your example code will be simple:

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

other examples can be found in test package: https://bitbucket.org/cache-kz/reflect4j/src/c344d76a4896235f6a1b09b2499d5ae25adc2900/src/test/java/kz/cache/reflect4j/ObjectManagerTest.java

cache
  • 662
  • 2
  • 14
  • 28