2012-01-31 120 views
2

我有一个类有几个领域是另一个类的子类。我想在顶层类中快速找到该子类的所有实例。有没有一个库可以给我一个在另一个类中出现的类的所有实例?

例如

public class TopClass { 
private ClassIWant1 myVar1; 
private ClassIWant2 myVar2; 
private OtherJunk myVar3; 
private Nested myVar4; 
} 

public class Nested { 
private ClassIWant3 myVar11; 
} 

public class SuperClass { 
} 

public ClassIWant1 extends SuperClass {} 
public ClassIWant2 extends SuperClass {} 
public ClassIWant3 extends ClassIWant1 {} 

如果我是通过与TopClass一个实例我希望得到包含myVar1,myVar2和myVar11值的列表来运行例子。

我对如何使用反射来手动执行此操作的一般想法,但我希望我没有推倒重来。有没有可以做到这一点的图书馆?

我熟悉ReflectUtils,但我不知道如果能够做到这一点或没有。

+0

作为参考,“快速”和“与反思”是......相互冲突的目标,除非你在的意义指的是“快”,“我不会写太多的代码。” – 2012-01-31 23:30:21

+0

@LouisWasserman - 公平点。我的意思是后者。我已经决定使用反射,这是一种性能损失。如果存在通用库,那么我至少可以节省一些维护和测试时间,而不用编写和测试我自己的代码。 – Freiheit 2012-01-31 23:34:58

回答

1

如果我明白你的要求正确,你正在寻找的东西是这样的:

public class Test { 
    public static void main(String[] args) { 
     TopClass top = …; // initialise as appropriate 
     System.out.println(findFields(top, SuperClass.class)); 
    } 

    private static <T> List<T> findFields(Object haystack, Class<T> needle) { 
     return findFields0(haystack, needle, new HashSet<Object>(), new ArrayList<T>()); 
    } 

    private static <T> List<T> findFields0(Object haystack, Class<T> needle, Set<Object> visited, List<T> result) { 
     if (visited.contains(haystack)) return result; // we already searched this object 

     visited.add(haystack); 

     for (Field field : haystack.getClass().getFields()) { 
      field.setAccessible(true); 
      Object fieldValue = null; 
      try { 
       fieldValue = field.get(haystack); 
      } catch (IllegalAccessException e) { 
       // shouldn't happen 
       throw new RuntimeException(e); 
      } 
      if (needle.isAssignableFrom(field.getType())) { 
       result.add(needle.cast(fieldValue)); 
      } 

      // recurse 
      findFields0(fieldValue, needle, visited, result); 
     } 
     return result; 
    } 
} 

这是通过使用静态类型的字段作为声明。也就是说,如果您声明一个字段为Object,但它包含SuperClass或其后代之一的实例,则不会找到该实例。如果字段将它们设置为值,它也将返回null。我不知道这会对原始类型做什么。

免责声明:代码在一个乐观的例子中进行了简短的测试,如果它导致您的计算机着火,我不承担任何责任。

+0

我认为这是有效的,但我不得不稍微按摩一下,才能与装有SuperClass实例的列表很好地玩。 – Freiheit 2012-02-01 15:57:01

+1

这很好。谢谢!我不得不添加一个else case以确定字段类型是否是ParameterizedType,然后获取实际类型,然后如果其中一个类型可从needle分配,则将fieldValue中的所有元素添加到结果中。 – Freiheit 2012-02-01 16:38:21

-1

this method你在找什么?

+0

是递归吗?我认为这给了我类的名字,但没有给出一个实例的字段的值。 – Freiheit 2012-01-31 23:32:06

+0

我不认为它是递归的,但我不认为编写一个递归调用这个方法会很困难。 – Dawood 2012-01-31 23:33:48

+0

-1:1)对于在网站上实际存在的问题的答案,而不是在用户的想象中,这是可取的。 2)该方法似乎与OP要求的内容没有关系。它将返回在类范围内声明的内部类,而不是其字段的值。 – millimoose 2012-02-01 00:29:27

相关问题