用于设置字段

时间:2017-11-12 22:10:33

标签: java reflection hashmap immutability

我使用反射相当新,我目前正在尝试为设置字段实现自定义反射工具。 看看SpringTots ReflectionsTestUtils,我对setFields的完成情况有了一些了解。我目前正试图通过将Object和ImmutableMap作为参数来实现它。

我们的想法是将hashmap中的Field / Key值与对象中存在的字段进行匹配。我理解整体想法,但我尝试实现的方法似乎不适用于从地图中检索字段并比较对象中的字段。

我的问题是: 有没有比我在下面尝试实现的更有效的方法来实现这一目标?

不确定我是否正确地走在这里并且会感谢所有给出的提示:

    public static void setField(Object object, ImmutableMap<String, Object> map)
  throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
      if (object instanceof Object) {
        Field[] fields = object.getClass().getDeclaredFields();

        for (Field aField : fields) {
         for (Map.Entry<String, Object> entry : map.entrySet()) {
          if (entry.getKey() instanceof Object) {
           String value = entry.getKey();
           checkPrimitiveValue(aField, object, value);
         }
        }
       }
    }

}

   private static void checkPrimitiveValue(Field field, Object object, String value) throws IllegalArgumentException, IllegalAccessException {
// Find out Primitive and parse the string to correct value
if (field.getType() == boolean.class) {
  field.setAccessible(true);
  field.set(object, Boolean.parseBoolean(value));
} else if (field.getType() == long.class) {
  field.setAccessible(true);
  field.set(object, Long.parseLong(value));
} else if (field.getType() == int.class) {
  field.setAccessible(true);
  field.set(object, Integer.parseInt(value));
} else if (field.getType() == double.class) {
  field.setAccessible(true);
  field.set(object, Double.parseDouble(value));
} else { // String is used
  field.setAccessible(true);
  field.set(object, value);
}

}

1 个答案:

答案 0 :(得分:1)

测试:

 if (object instanceof Object)

没用,除非对象为null,所以这是一个更好的写入方式:

 if (object != null)

您将地图中的每个键分配给对象的每个字段。我猜你想做点什么:

    public static void setField(Object object, ImmutableMap<String, Object> map)
  throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
        if (object != null) {
            Field[] fields = object.getClass().getDeclaredFields();

            for (Field aField: fields) {
                Object value = map.get(aField.getName());
                assignValue(aField, object, value);
            }
        }
    }

现在我不明白为什么你要传递假设地图中的值是字符串(静态类型是对象)。

private static void assignValue(Field field, Object object, Object value)
    throws IllegalArgumentException, IllegalAccessException,
            NoSuchFieldException, SecurityException {
    field.setAccessible(true);
    if (field.getType().isPrimitive())
        if (value == null) {
            value = defaultValue(field.getType());
        } else if (value instanceof String) {
            value = parseValue(field.getType(), (String)value);
        }
    }
    field.set(object, value);
}

基元类型的默认值:

private static Object defaultValue(Class<?> clazz) {
    if (clazz == boolean.class) {
        return Boolean.FALSE;
    } else if (clazz == char.class) {
        return (char)0;
    } else if (clazz == byte.class) {
        return (byte)0;
    } else if (clazz == short.class) {
        return (short)0;
    } else if (clazz == int.class) {
        return 0;
    } else if (clazz == long.class) {
        return 0L;
    } else if (clazz == float.class) {
        return 0F;
    } else if (clazz == double.class) {
        return 0.0;
    } else {
        throw new IllegalArgumentException("Not a primitive type");
    }
}

从字符串转换为基本类型(我不知道你为什么要这样做,但这里是):

private static Object parseValue(Class<?> type, String s) {
    if (type == boolean.class) {
        return Boolean.valueOf(s);
    } else if (type == char.class) {
        return (char)Integer.parseInt(s);
    } else if (type == byte.class) {
        return Byte.valueOf(s);
    } else if (type == short.class) {
        return Short.valueOf(s);
    } else if (type == int.class) {
        return Integer.valueOf(s);
    } else if (type == long.class) {
        return Long.valueOf(s);
    } else if (type == float.class) {
        return Float.valueOf(s);
    } else if (type == double.class) {
        return Double.valueOf(s);
    } else {
        throw new IllegalArgumentException("Not a primitive type");
    }
}