通过反射存在或不存在查找字段

时间:2013-12-05 11:26:35

标签: java reflection

我的班级结构如下

   ClassA{}
   ClassB extends ClassA{}
   ClassC extends ClassB{}

这些类包含一个字段name,我不知道该字段存在于哪个类中,我有一个string nameClassC的对象。我正在使用反射来获取我的代码

的字段
  private static Field getType(Object obj,String fieldName){

            Field type = null;
            try
            {
                    type = obj.getClass().getDeclaredField(fieldName);
            } 
            catch (NoSuchFieldException e) {
                    try
                    {
                            type = obj.getClass().getSuperclass().getDeclaredField(fieldName);
                    }
                    catch (NoSuchFieldException e1) {
                            e.printStackTrace();
                    }
            } catch (SecurityException e) {
                    e.printStackTrace();
            }
            return type;
    }

但它只检查当前类及其超类中的字段,如果我想检查字段直到顶级类,我需要继续写try catch块。我认为这不是正确的方法。有没有替代解决方案呢? 提前致谢

5 个答案:

答案 0 :(得分:4)

我认为您正在尝试做类似的事情:

   Class cls = obj.getClass();        
    for (Class acls = cls; acls != null; acls = acls.getSuperclass()) {
      try {
        Field field = acls.getDeclaredField(fieldName);
        // if not found exception thrown
        // else return field
        return field;
      } catch (NoSuchFieldException ex) {
        // ignore
      }
    }

答案 1 :(得分:2)

使用getField代替getDeclaredField。如果在给定的类中没有立即找到接口和父类中的字段,它将在接口和父类中查找字段。

答案 2 :(得分:2)

将try块包装到循环中怎么样:

Field type = null;  
Class clz = object.getClass();
while(clz != null || clz != Object.class) {
    try
    {
        type = clz.getDeclaredField(fieldName);
        break;
    } catch (NoSuchFieldException e) {
        clz = object.getSuperclass();
    } 
}
return type;

答案 3 :(得分:0)

你可以使用while(或任何其他类似的)循环来保持扫描,直到找到匹配为止。

private static Field getType(Object obj,String fieldName){

Field type = null;
Class clazz = obj.getClass();
while (type==null && clazz!=null) {
   try {
       type = obj.getClass().getDeclaredField(fieldName);
   } catch (NoSuchFieldException e) {
       clazz = clazz.getSuperClass();
   } catch (SecurityException e) {
       e.printStackTrace();
       return null;
   }
   return type;
}

最好检查字段是否存在而不是使用异常来控制流程,但这样可行。

答案 4 :(得分:0)

试试这个,它将处理超类和嵌套属性。

public static boolean isFieldExist(Class<?> clazz, String property) {
String[] fields = property.split("\\.");

    try {
        Field file = clazz.getDeclaredField(fields[0]);

        if (fields.length > 1) {
            return isFieldExist(file.getType(), property.substring(property.indexOf('.') + 1, property.length()));
        }

        return true;
    } catch (NoSuchFieldException | SecurityException e) {
        if (clazz.getSuperclass() != null) {
            return isFieldExist(clazz.getSuperclass(), property);
        }

        return false;
    }
}