Как мы проверяем, совместимо ли значение объекта с полем примитивного типа в Java

1

Я хочу разработать bindTo утилиты bindTo который инициализирует все поля объекта (т. bindTo target) всеми совместимыми значениями, содержащимися в Map<String, Object> (где ключ - это имя поля). Предположим, что f представляет поле в target объекте, а vals - это Map содержащая значения инициализации, поэтому я должен:

  1. проверьте, содержит ли карта vals запись с ключом, равным имени поля.
  2. если эта запись существует, тогда я должен проверить, совместимо ли ее значение с типом полей.
  3. и если это так, то я должен установить это значение в поле 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())

Итак, есть ли у вас предложение подавить это ограничение с помощью полей примитивного типа?

Теги:
reflection

2 ответа

0
Лучший ответ

Если целевое поле является примитивным типом, вы можете получить его значение по умолчанию с помощью отражения, которое, в свою очередь, будет помещено в пакетный объект. Из этого объекта вы можете получить соответствующий тип оболочки. Таким образом, вы можете заменить следующую строку своего кода:

Class<?> fType = f.getType();

с:

Class<?> fType = f.getType();
if(fType.isPrimitive()){
  fType = f.get(target).getClass();
}
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;
      }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню