gpt4 book ai didi

java - 设置字段的自定义反射方法

转载 作者:行者123 更新时间:2023-12-02 12:00:58 26 4
gpt4 key购买 nike

我对使用反射相当陌生,目前正在尝试实现自定义反射实用程序来设置字段。看了springboots ReflectionsTestUtils,我对setFields是如何完成的有了一个大概的了解。我目前正在尝试通过使用 Object 和 ImmutableMap 作为参数来实现这一点。

其思想是将 HashMap 中的字段/键值与对象中存在的字段进行匹配。我理解总体思路,但我尝试实现的方法似乎不适用于从 map 中检索字段并比较对象中的字段。

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

不确定我是否走对了路,并且希望得到所有给出的提示:

    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);
}

}

最佳答案

测试:

 if (object instanceof Object)

没有什么用处,除非 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");
}
}

关于java - 设置字段的自定义反射方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47254583/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com