我试图定义一个fieldName->方法映射,我可以重用多个实例。我的想法是,我将只使用反射一次,而不是每个实例。
例如,给定下面的Client类,Map将有'name'指向一个对应于getName()的方法对象- 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));
}
对于这个目的,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);
其他示例可以在test package中找到:https://bitbucket.org/cache-kz/reflect4j/src/c344d76a4896235f6a1b09b2499d5ae25adc2900/src/test/java/kz/cache/reflect4j/ObjectManagerTest.java