Я хочу разработать bindTo
утилиты bindTo
который инициализирует все поля объекта (т. 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 fields 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())
Итак, есть ли у вас предложение подавить это ограничение с помощью полей примитивного типа?
Если целевое поле является примитивным типом, вы можете получить его значение по умолчанию с помощью отражения, которое, в свою очередь, будет помещено в пакетный объект. Из этого объекта вы можете получить соответствующий тип оболочки. Таким образом, вы можете заменить следующую строку своего кода:
Class<?> fType = f.getType();
с:
Class<?> fType = f.getType();
if(fType.isPrimitive()){
fType = f.get(target).getClass();
}
Вы можете использовать вспомогательную службу, чтобы получить соответствующий тип обертки примитивного, такие как 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;
}
}