I want to develop a bindTo
utility method that initializes all the fields of an object (ie the target
) with all compatible values contained in a Map<String, Object>
(where the key is the name of the field). Consider that f
represents a field in the target
object and vals
is the Map
containing the initialization values, so I must:
vals
contains an entry with a key equals to the field name. f
in the target
object. This corresponds to the following code:
/*
* 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);
}
}
Yet, this approach does not work when we have primitive type fields, because a wrapper type is not compatible with the corresponding primitive type. For instance, an Integer
type is not compatible with an int
and will not satisfy the condition: fType.isAssignableFrom(fValue.getClass())
So, do you have any suggestion to suppress this limitation with primitive type fields?
If the target field is a primitive type, then you can get its default value via reflection, which in turn will be boxed in a wrapper object. From this object you may get the corresponding wrapper type. So, you can replace the following line of your code:
Class<?> fType = f.getType();
with:
Class<?> fType = f.getType();
if(fType.isPrimitive()){
fType = f.get(target).getClass();
}
You can use an auxiliary service to get the corresponding wrapper type of a primitive, such as the toWrapper
method of the WrapperUtilites
class provided bellow. So instead of writing:
Class<?> fType = f.getType();
You may write:
Class<?> fType = WrapperUtilites.toWrapper(f.getType());
The WrapperUtilites
can be written such as:
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;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.