有没有一个库可以给我一个在另一个类中出现的类的所有实例?
我有一个类有几个领域是另一个类的子类。我想在顶层类中快速找到该子类的所有实例。有没有一个库可以给我一个在另一个类中出现的类的所有实例?
例如
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,但我不知道如果能够做到这一点或没有。
如果我明白你的要求正确,你正在寻找的东西是这样的:
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
。我不知道这会对原始类型做什么。
免责声明:代码在一个乐观的例子中进行了简短的测试,如果它导致您的计算机着火,我不承担任何责任。
是this method你在找什么?
是递归吗?我认为这给了我类的名字,但没有给出一个实例的字段的值。 – Freiheit 2012-01-31 23:32:06
我不认为它是递归的,但我不认为编写一个递归调用这个方法会很困难。 – Dawood 2012-01-31 23:33:48
-1:1)对于在网站上实际存在的问题的答案,而不是在用户的想象中,这是可取的。 2)该方法似乎与OP要求的内容没有关系。它将返回在类范围内声明的内部类,而不是其字段的值。 – millimoose 2012-02-01 00:29:27
作为参考,“快速”和“与反思”是......相互冲突的目标,除非你在的意义指的是“快”,“我不会写太多的代码。” – 2012-01-31 23:30:21
@LouisWasserman - 公平点。我的意思是后者。我已经决定使用反射,这是一种性能损失。如果存在通用库,那么我至少可以节省一些维护和测试时间,而不用编写和测试我自己的代码。 – Freiheit 2012-01-31 23:34:58