我想开发一个bindTo
实用程序方法,用于初始化对象的所有字段(即target
),其中包含Map<String, Object>
中包含的所有兼容值(其中键是该字段的名称)。
请注意f
表示target
对象中的字段,vals
表示包含初始值的Map
,因此我必须:
vals
是否包含密钥等于字段名称的条目。f
对象中的字段target
。这对应于以下代码:
/*
* 1. checks if the map `vals` contains an entry with a key equals to the field name:
*/
String fName = f.getName();
if(vals.containsKey(fName)){
/*
* 2. if that entry exists, then checks if its value is compatible with the field’s type:
*/
Class<?> fType = f.getType();
Object fValue = vals.get(fName);
if(fType.isAssignableFrom(fValue.getClass())){
/*
* 3. and if it is, then set that value to the field `f` in the `target` object:
*/
f.setAccessible(true);
f.set(target, fValue);
}
}
然而,当我们有原始类型字段时,这种方法不起作用,因为包装类型与相应的基元类型不兼容。例如,Integer
类型与int
不兼容,并且不符合条件:fType.isAssignableFrom(fValue.getClass())
那么,你有什么建议用原始类型字段来抑制这种限制吗?
答案 0 :(得分:0)
如果目标字段是基本类型,则可以通过反射获取其默认值,反射又将在包装器对象中加载。从这个对象,您可以获得相应的包装类型。因此,您可以替换以下代码行:
Class<?> fType = f.getType();
使用:
Class<?> fType = f.getType();
if(fType.isPrimitive()){
fType = f.get(target).getClass();
}
答案 1 :(得分:0)
您可以使用辅助服务来获取基元的相应包装类型,例如下面提供的toWrapper
类的WrapperUtilites
方法。所以不要写:
Class<?> fType = f.getType();
你可以写:
Class<?> fType = WrapperUtilites.toWrapper(f.getType());
WrapperUtilites
可以写成:
class WrapperUtilites{
final static Map<Class<?>, Class<?>> wrappers = new HashMap<>();
static{
wrappers.put(boolean.class, Boolean.class);
wrappers.put(short.class, Short.class);
wrappers.put(int.class, Integer.class);
…
// do this for all primitive types
}
public static Class<?> toWrapper(Class<?> c){
return c.isPrimitive()? wrappers.get(c) : c;
}
}