繁体   English   中英

设置作为另一个对象的子对象的对象的字段值

[英]Setting a field value of an object that is a child of another object

我收到以下异常:

java.lang.IllegalArgumentException:对象不是该类的实例

我对为什么得到它有一个很好的想法-但我一直坚持寻找解决方案。

这是示例代码来解释我要做什么:

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”,该对象所有者是汽车的一部分。 现在,我想读取(然后进行修改,但是我已经无法读取)字段“名称”的值。 问题:我只有car的实例,但没有其“ owner”字段的实例。 为了澄清起见:所描述的过程将通用地工作-所以我将不知道获取器,设置器,字段等的名称。

这是失败的代码(请让我知道是否需要更多代码来澄清问题):

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操纵它,而对象c的对象又是对象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

该字段只会为您提供给定班级的字段。 它不会导航到类并获取子字段。

我建议您改用像这样的普通获取字段助手

  String name = (String) getField(car, datapathToFeature);

好的,感谢Peter为我的大脑拨开了所需的戳戳;)我找到了解决方案,这里是:

我创建一个DatapathObject,其中包含字段和父对象作为对象。 在进行比较之前,我无法获得Owner对象的实例,该对象是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));
}

再次感谢Peter-lol,我仍然不明白您的答案,我也不认为这是我想要的,但是它为我的大脑提供了寻找答案的失落之星:)!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM