我有一个非常复杂的类,比如
classA {
public classB b;
}
classB {
public classC c;
}
classC {
public List<classD> d;
}
...
现在,给定一个实例的类a,和一个字段路径像'b.c.d.e.f.g',是否有一个简单的方法来获得目标字段值通过反射?有没有现有的图书馆之类的?
许多谢谢。
没有"easy"使用b.c.d.e.f
这样的字段路径来导航到classD
元素列表绝对不是一种简单的方法,因为(在某些时候)您需要指定您正在查看的List
中的哪个元素。
然而,我们可以使用反射在一个字段队列中导航。尽管在这个简单的例子中,我们不能从List
中挑选元素,但我们仍然可以检查List
本身的属性,例如size
。
(下面的例子直接访问这个私有变量——绝对不建议)——但是你的问题是关于反射的,所以为了说明,我们把这些重要的问题放在一边)
对于这个特定的示例,结果输出将是RESULT of b.c.d.size: 3
,因为我们在初始化变量时将三个new ClassD()
对象塞进了List
。
public static void main(final String args[]) throws Exception
{
// Initialize all variables
final ClassA a = new ClassA();
a.b = new ClassB();
a.b.c = new ClassC();
a.b.c.d = new ArrayList<>(Arrays.asList(new ClassD(), new ClassD(), new ClassD()));
// Traverse these member variables
final String fieldPath = "b.c.d.size";
// Build the list of paths from the string
final Queue<String> fieldPaths = new ArrayDeque<>(Arrays.asList(fieldPath.split("\.")));
// Display the output
System.out.println("RESULT of ".concat(fieldPath).concat(": ").concat(discover(a, fieldPaths).toString()));
}
public static Object discover(final Object o, final Queue<String> fieldPaths) throws Exception
{
// End of the queue, return the object found most recently
if (fieldPaths.isEmpty())
{
return o;
}
final String nextFieldPath = fieldPaths.remove();
final Field f = o.getClass().getDeclaredField(nextFieldPath);
// Go ahead and access private/protected data anyway... it's fine! what could go wrong
f.setAccessible(true);
return discover(f.get(o), fieldPaths);
}
protected static class ClassA
{
public ClassB b;
}
protected static class ClassB
{
public ClassC c;
}
protected static class ClassC
{
public List<ClassD> d;
}
protected static class ClassD
{
// Empty block
}
感谢大家的留言。
谢谢Tim, commons-beanutils在处理pojo类时帮助很大,它在List/Map字段中工作得很好。
这几乎是我所需要的,除了一些极端情况,例如,当给出一个没有提供索引的List时。
我认为最好是在commons- beauutils的帮助下编写我自己的工具。