Java 获取给定分层路径的字段值

Java 获取给定分层路径的字段值,java,recursion,Java,Recursion,我有一个包含子属性的对象,它也有子属性等等 我基本上需要找到检索对象上特定字段的值的最佳方法,因为它是一个字符串的完整层次路径 例如,如果对象具有具有字段id(字符串)的字段客户机(对象)的字段公司(对象),则此路径将表示为company.client.id。因此,给定一条指向我试图获取对象上的值的字段的路径,我将如何进行此操作 干杯。请在下面的Fieldhelper类中找到getFieldValue方法。 它应该能让你很快地解决你的问题 拆分字符串,然后递归地应用getFieldValue,将

我有一个包含子属性的对象,它也有子属性等等

我基本上需要找到检索对象上特定字段的值的最佳方法,因为它是一个字符串的完整层次路径

例如,如果对象具有具有字段id(字符串)的字段客户机(对象)的字段公司(对象),则此路径将表示为
company.client.id
。因此,给定一条指向我试图获取对象上的值的字段的路径,我将如何进行此操作


干杯。

请在下面的
Fieldhelper
类中找到
getFieldValue
方法。 它应该能让你很快地解决你的问题 拆分字符串,然后递归地应用
getFieldValue
,将结果对象作为下一步的输入

package com.bitplan.resthelper;
import java.lang.reflect.Field;

/**
 * Reflection help
 * @author wf
 *
 */
public class FieldHelper {

    /**
     * get a Field including superclasses
     * 
     * @param c
     * @param fieldName
     * @return
     */
    public Field getField(Class<?> c, String fieldName) {
        Field result = null;
        try {
            result = c.getDeclaredField(fieldName);
        } catch (NoSuchFieldException nsfe) {
            Class<?> sc = c.getSuperclass();
            result = getField(sc, fieldName);
        }
        return result;
    }

    /**
     * set a field Value by name
     * 
     * @param fieldName
     * @param Value
     * @throws Exception
     */
    public void setFieldValue(Object target,String fieldName, Object value) throws Exception {
        Class<? extends Object> c = target.getClass();
        Field field = getField(c, fieldName);
        field.setAccessible(true);
        // beware of ...
        // http://docs.oracle.com/javase/tutorial/reflect/member/fieldTrouble.html
        field.set(this, value);
    }

    /**
     * get a field Value by name
     * 
     * @param fieldName
     * @return
     * @throws Exception
     */
    public Object getFieldValue(Object target,String fieldName) throws Exception {
        Class<? extends Object> c = target.getClass();
        Field field = getField(c, fieldName);
        field.setAccessible(true);
        Object result = field.get(target);
        return result;
    }

}
package com.bitplan.resthelper;
导入java.lang.reflect.Field;
/**
*反思帮助
*@author wf
*
*/
公共类FieldHelper{
/**
*获取包含超类的字段
* 
*@param c
*@param fieldName
*@返回
*/
公共字段getField(c类,字符串字段名){
字段结果=空;
试一试{
结果=c.getDeclaredField(fieldName);
}捕获(NoSuchFieldException nsfe){
类sc=c.getSuperclass();
结果=getField(sc,fieldName);
}
返回结果;
}
/**
*按名称设置字段值
* 
*@param fieldName
*@param值
*@抛出异常
*/
public void setFieldValue(对象目标、字符串字段名、对象值)引发异常{

类您需要首先拆分字符串以获得单个
字段名
。然后对于每个字段名,获得所需的信息。您必须迭代字段名数组

您可以尝试下面的代码。虽然我没有使用递归,但它可以工作:-

public static void main(String[] args) throws Exception {

    String str = "company.client.id";
    String[] fieldNames = str.split("\\.");

    Field field;

    // Demo I have taken as first class that contains `company`
    Class<?> targetClass = Demo.class;  
    Object obj = new Demo();

    for (String fieldName: fieldNames) {

        field =  getFieldByName(targetClass, fieldName);    
        targetClass = field.getType();

        obj = getFieldValue(obj, field);            
        System.out.println(field + " : " + obj);

    }

}

public static Object getFieldValue(Object obj, Field field) throws Exception {
    field.setAccessible(true);
    return field.get(obj);
}

public static Field getFieldByName(Class<?> targetClass, String fieldName) 
                                                        throws Exception {
    return targetClass.getDeclaredField(fieldName);
}
publicstaticvoidmain(字符串[]args)引发异常{
String str=“company.client.id”;
字符串[]字段名=str.split(\\);
场域;
//演示我已经作为第一类,其中包含“公司”`
Class targetClass=Demo.Class;
Object obj=新的Demo();
for(字符串字段名:字段名){
field=getFieldByName(targetClass,fieldName);
targetClass=field.getType();
obj=getFieldValue(obj,字段);
系统输出打印项次(字段+“:”+obj);
}
}
公共静态对象getFieldValue(对象obj,字段)引发异常{
字段。setAccessible(true);
返回字段.get(obj);
}
公共静态字段getFieldByName(类targetClass,字符串fieldName)
抛出异常{
返回targetClass.getDeclaredField(fieldName);
}
您可以使用
PropertyUtilsBean

使用示例:

PropertyUtilsBean pub = new PropertyUtilsBean();
Object property = pub.getProperty(yourObject, "company.client.id");

您可能需要在
反射API
中使用类。看起来是又一次尝试将URL发布到您的bitplan网站。此外,您尝试包含许可证与您最初在此处发布内容时同意的许可证相反。我正在编辑您的许可证文本/链接。请勿重新添加,否则我将标记为垃圾邮件。Andrew我不清楚许可证的FAQ解释是否允许删除对作者的直接引用。这将成为我在此处共享更多源代码的障碍。很高兴知道这一点!“作者”是你;你已经在每篇文章的作者框中显示为作者。如果你包含了其他人的代码,你将不得不包含该信息。但是,如果其他人的代码使用的许可证与你在发布时默认的许可证不同,你通常根本无法发布它。a接受的答案很好学,但这个答案很好编码。只有在定义了getter和setter之后,这才是正确的