スプリングを依存関係として使用しても問題ないと仮定すると、提案されているプロキシ アプローチを使用できます。BeanUtils クラスは、メソッド名をプロパティ記述子に変換して、名前を取得できるようにします。インターフェイス自体を操作しているため、型変換は必要ありません。そのため、コンパイラは正しい型を送信する (したがって、正しい型を出力する) ことを保証します。
static interface Person {
void setName(String name);
String getName();
void setAge(int age);
int getAge();
}
public static Person createPerson() {
return createPerson(new HashMap<String, String>());
}
public static Person createPerson(final Map<String, String> props) {
InvocationHandler ih = new InvocationHandler() {
private TypeConverter typeConverter = new SimpleTypeConverter();
@Override
public Object invoke(Object source, Method method, Object[] params)
throws Throwable {
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
if (method.getName().startsWith("set")) {
props.put(pd.getName(), typeConverter.convertIfNecessary(params[0], String.class));
return null;
}
else if (method.getName().startsWith("get") ||
method.getName().startsWith("is")) {
Object res = props.get(pd.getName());
return typeConverter.convertIfNecessary(res, method.getReturnType());
}
return null;
}
};
Person p = (Person) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class<?>[] { Person.class },
ih);
return p;
}
public static void main(String args[]) {
final Map<String, String> props = new HashMap<String, String>();
props.put("name", "Matt");
props.put("age", "4");
Person p = createPerson(props);
System.out.println(p.getName());
System.out.println(p.getAge());
}