【发布时间】:2019-02-25 17:06:54
【问题描述】:
我想转换 Object 的每个 String 属性(连同它的嵌套对象),我正在使用以下递归方法通过反射 API 来实现:
public static void reflect(Object obj) {
if (obj == null) {
return;
}
Class klazz = obj.getClass();
if (klazz.isPrimitive()
|| obj instanceof Integer
|| obj instanceof Double
|| obj instanceof Boolean)
return;
else {
try {
for (Field field : klazz.getDeclaredFields()) {
field.setAccessible(true);
Object f = field.get(obj);
if(f instanceof String) {
f = transform(f);
field.set(obj, f);
}
else {
reflect(f);
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
}
private static Object transform(Object f) {
f = f + "blabla";
return f;
}
@Data
@Builder
public class PrintObject {
private String field1;
private String field2;
private String field3;
private NestedObject field4;
}
@Data
@Builder
public class NestedObject {
private String field1;
private String field2;
private Integer field3;
}
NestedObject nestedObject = NestedObject
.builder()
.field1("test")
.field2("test2")
.field3(1)
.build();
PrintObject printObject = PrintObject
.builder()
.field1("test")
.field2("Test")
.field3("test")
.field4(nestedObject)
.build();
Utils.reflect(printObject);
到目前为止,一切正常,如果我执行此操作,那么所有字符串值最后都会附加“blabla”。 如果 PrintObject 有其他数据结构,如 List 或 Map,就会出现问题。 例如,如果 PrintObject 类中有另一个字段:
private List<String> field5;
那么这个代码执行会抛出 StackOverflowError。
List<String> list = new ArrayList<>();
list.add("test");
NestedObject nestedObject = NestedObject
.builder()
.field1("test")
.field2("test2")
.field3(1)
.build();
PrintObject printObject = PrintObject
.builder()
.field1("test")
.field2("Test")
.field3("test")
.field4(nestedObject)
.field5(list)
.build();
Utils.reflect(printObject);
您知道如何使用这些结构来实现这一点吗? 提前致谢。
field5 也可以是例如:
Map<String,String>
甚至
List<List<String>>
【问题讨论】:
-
你想为
List和Map做什么?你想在Map中转换keys吗? -
Matt Champion 已经就循环的来源提供了一个很好的答案。至于列表和地图处理——您必须为它们添加一个特殊情况并遍历元素而不是遍历这些类的内部字段。请注意,由于类型擦除,您将无法通过反射确定列表的参数化类型——您必须逐个检查所有元素并检查它们的类型。但是您将面临一些更有趣的挑战,例如如何处理您根本无法更改的不可变字符串列表。
-
我可以添加一个方法来遍历列表的所有元素并修改值(如果它们是字符串)。那行得通。但是,如果我们有一个像 List
- >> 或 Map
> 这样的数据结构,我想修改这些数据结构的所有字符串值怎么办?
标签: java reflection