我收到以下异常:
java.lang.IllegalArgumentException:object不是类的实例
我非常清楚我为什么会这样做 - 但我仍然坚持寻找解决方案。
以下是解释我想要做的示例代码:
public class Car {
private Owner owner;
//Constructor and getter for owner field
}
public class Owner {
private String name;
//Constructor and getter for name field
}
现在我要做的是:从Car类开始,我检索名为“owner”的字段 - 然后我检索该对象所有者的字段“name”,该字段是汽车的一部分。现在我想阅读(以后修改,但我已经失败并阅读)字段“name”的值。问题:我只有一个汽车的实例,但不是它的领域“所有者”。为了澄清目的:所描述的过程应该一般工作 - 所以我不知道吸气剂,制定者,字段等的名称。
以下是失败的代码(如果需要更多代码来澄清问题,请告诉我):
Car car = new Car();
//Set owner and name property of owner for car
...
Field nameField = resolveDatapath(datapathToFeature, car);
nameField.setAccessible(true);
//Here I fail with the afore mentioned IllegalArgumentException, because
//indeed, I am passing car - not its sub-object "owner" (because as I can see it,
//there is no way for me to generically retrieve the owner object - or is there?)
String value = nameField.get(car).toString();
上面的东西也适用于任何“深度”(比方说我想要一个字段并从对象c操纵它,对象c是对象b的字段,而对象字段a又是...)
请告诉我,如果我可以进一步澄清问题 - 这是检索字段的代码(在上面的例子中是nameField):
private Field resolveDatapath(String path, Object parent) {
String subString = path;
if (!subString.contains("."))
{
//We haven reached the end of the path
return getField(subString, parent.getClass());
}
//We haven't reached the end of the
subString = path.substring(0, path.indexOf("."));
Field field = getField(subString, parent.getClass());
return resolveDatapath(path.substring(path.indexOf(".")+1), field);
}
private Field getField(String name, Class<?> parent) {
Field [] fields = parent.getDeclaredFields();
for(Field f : fields)
{
String current = f.getName();
if(current.equalsIgnoreCase(name))
{
try {
return parent.getDeclaredField(current);
} catch (SecurityException e) {
fail("Not allowed to access field - " + current);
} catch (NoSuchFieldException e) {
fail("No such field exists - " + current);
}
}
}
return null;
}
非常感谢您提前, 最好的祝福, Ready4Android
答案 0 :(得分:0)
Field只会为您提供给定类的字段。它不会导航到类并获取子字段。
我建议您使用像这样的普通get字段助手
String name = (String) getField(car, datapathToFeature);
答案 1 :(得分:0)
好的,感谢彼得为我的大脑提供所需的戳;)我找到了解决方案,现在是:
我创建了一个DatapathObject,它包含字段和父对象作为对象。在我进行编辑之前,我无法获得所有者对象的实例,该对象是Car对象中的一个字段。当然,正如我现在想的那样,这完全是胡说八道 - 我的脑子在这里有点慢:P。
此代码有效并使我的单元测试通过:
public void testDatapathResolution() throws Exception{
String[] path = datapathToFeature.split("\\.");
assertEquals("Owner", path[0]);
assertEquals("Name", path[1]);
DatapathObject result = resolveDatapath(datapathToFeature, car);
result.getField().setAccessible(true);
Object value = result.getField().get(result.getParent());
assertEquals(car.getOwner().getName(), value.toString());
}
这是DatapathObject类:
public class DatapathObject {
private Object parent;
private Field field;
public DatapathObject(Object parent, Field field) {
this.parent = parent;
this.field = field;
}
public Object getParent() {
return parent;
}
public Field getField() {
return field;
}
}
我的resolveDatapath方法如下所示(为了适应DatapathObject的引入:
private DatapathObject resolveDatapath(String path, Object parent) throws
IllegalArgumentException, IllegalAccessException
{
String subString = path;
if (!subString.contains("."))
{
//We haven reached the end of the path
Field field = getField(subString, parent.getClass());
return new DatapathObject(parent, field);
}
//We haven't reached the end of the
subString = path.substring(0, path.indexOf("."));
Field field = getField(subString, parent.getClass());
field.setAccessible(true);
return resolveDatapath(path.substring(path.indexOf(".")+1),
field.get(parent));
}
再次感谢彼得 - 大声笑我仍然不明白你的答案,我不认为这是我正在寻找的东西,但它为我的大脑提供了缺失的火花,以找到答案:)!