3

My class structure is as follows

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

these classes contains a field say name, I did not know in which class this field is present, i have a string name and object of ClassC. I am using reflection to get the field my code is

  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;
    }

But it will check for field only in the current class and its super class, if i want to check the field till top level class, I need to keep write try catch blocks. i think it is not the correct way. Is there any alternate solution for this? Thanks in advance

Deepak Bhatia
  • 6,230
  • 2
  • 24
  • 58
Siva
  • 1,938
  • 1
  • 17
  • 36

5 Answers5

5

I think that you are trying to do something like:

   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
      }
    }
homik
  • 553
  • 5
  • 9
2

Use getField instead of getDeclaredField. It will look for the field in interfaces and parent classes recursively if it's not found immediately in the given class.

Joni
  • 108,737
  • 14
  • 143
  • 193
  • 1
    Thanks for reply, but all my fields are private so i can not get the fields using getfields i guess, please correct me if i am wrong – Siva Dec 05 '13 at 11:30
  • If your fields are private, then the subclass would not have inherited them anyway. – NickJ Dec 05 '13 at 11:32
  • Correct: `getField` only gets public fields. – Joni Dec 05 '13 at 11:32
  • @NickJ: you are write, So if i use getField, it is throwing nosuchfield exception, though my class has the field name(private) – Siva Dec 05 '13 at 11:35
2

What about wrapping try block into the loop:

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;
sigito
  • 96
  • 4
0

You can use a while (or any other similar) loop to keep scanning down until you find a match.

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;
}

It would be better to check if the field exists rather than using the exception to control flow but this will work.

Tim B
  • 40,716
  • 16
  • 83
  • 128
0

Try this it will take care of superclass and nested properties.

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;
    }
}
Sabir Hussain
  • 175
  • 2
  • 9