简体   繁体   中英

How do we check if an object value is compatible with a primitive type field in Java

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:

  1. check if the map vals contains an entry with a key equals to the field name.
  2. if that entry exists, then I have to check if its value is compatible with the field's type.
  3. and if it is, then I must set that value to the field 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM