Java反思,有没有简单的方法通过'field path'获取字段值?

Java reflection, is there an easy way to get field value by 'field path'?

我有一个非常复杂的 class,比如,

classA {
  public classB b;
}

classB {
  public classC c;
}

classC {
  public List<classD> d;
}
...

现在,给定一个 classA 的实例,以及一个像 'b.c.d.e.f.g' 这样的字段路径,是否有一种简单的方法可以通过反射获取目标字段值?任何现有的图书馆或什么?

非常感谢。

没有一种“简单”的方法(并且绝对没有一种简单的方法可以通过使用像 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
}

谢谢大家 post。

谢谢 Tim,commons-beanutils 在处理 pojo 类 时很有帮助,它在 List/Map 领域工作得很好。

这几乎是我所需要的,除了一些极端情况,例如,当给出一个没有提供索引的列表时。

我认为要走的路是在 commons-beanutils 的帮助下编写我自己的工具。