设置对象的字段值是另一个对象

问题描述:

我收到以下异常的孩子:设置对象的字段值是另一个对象

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类开始,我取回了名为“老板”的领域 - 然后我检索作为汽车一部分的对象所有者的字段“名称”。现在我想阅读(后来修改,但我已经失败并阅读)字段“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,这是一个对象b的领域,这又是一个对象a的领域操纵它...)

请让我知道,如果我可以进一步澄清问题 - 这里是代码检索该字段(在上面的示例中为其名称字段):

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

好感谢彼得给了我的大脑捅它需要;)我找到了解决方案,那就是:

我创建一个包含字段和父对象作为对象的DatapathObject。在我接受合作之前,我无法获得Car对象中字段的Owner对象的实例。当然,正如我现在所认为的那样,这是胡说八道 - 我的大脑在这里变得有些缓慢: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类:chanded如下

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我还是不明白你的答案,我不认为这是我一直在寻找,但它提供了我的大脑缺少火花找到答案:)!

实地只会给你一个给定的类的字段。它不会导航到类并获取子字段。

我建议,而不是你使用一个普通的GET场帮手这样

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

感谢您的建议 - 但我不知道我完全理解你的答案:) ......我已经是路径,我需要像场:Car.Owner.Name(所有者类名称字段,在汽车类中的字段) - 我的问题是设置和获取name字段的值,因为我没有父对象作为一个实例(我只能检索它作为一个字段)哎......哈哈而我写这篇我有另一个想法......我会回来的更新:) – Ready4Android 2011-04-19 13:36:02