3

Possible Duplicate:
Access to private inherited fields via reflection in Java

Hello i hava got problem with init value with java reflection.

i have got simple class

 public class A extends B {
     private String name;
 }

  public class B {
     private String superName;   
  }

and also i have got simple function:

   public void createRandom(Class<T> clazz , List<String> classFields){


    try {
        T object = clazz.newInstance();
        for(String s : classFields){
            clazz.getDeclaredField(s);
        }

    } catch(Exception e){

    }

   }

My function do other stuff but i have got problem because i have got error :

java.lang.NoSuchFieldException: superName

How can i set all class field also field from super Class using reflection ??

I have got all class fields (also inherited) and i am using function field.set(Object obj, Object value) but in this way i can not set inherited class fields :/

I havent got problem to get all class field i am using Spring ReflectionUtils.doWithfield. i stored all field names in List<String> classField, so i known all clazz fields also inherited. But my problem is how to set values into all clazz fields.

Community
  • 1
  • 1
Łukasz Woźniczka
  • 1,625
  • 3
  • 28
  • 51
  • How are you invoking `createRandom()`? what are the values of `clazz` and the list? – amit Sep 18 '12 at 21:32

4 Answers4

8

If I had to guess, I'm assuming you are calling this method on class A, and expecting to be able to view the underlying fields declared in class B, like so:

A.class.getDeclaredField("superName");

This is not the case, and will throw an Exception (java.lang.NoSuchFieldException). Reflection does not check super classes to find fields or methods. So since class A doesn't define superName, it will not be found using reflection like that. However, you could modify your code to make it check all superclasses until it reaches null as the superclass, at which point if it's still not found, it definately doesn't exist.

Here's an example:

public static Field findUnderlying(Class<?> clazz, String fieldName) {
    Class<?> current = clazz;
    do {
       try {
           return current.getDeclaredField(fieldName);
       } catch(Exception e) {}
    } while((current = current.getSuperclass()) != null);
    return null;
}

Here's an example call: findUnderlying(A.class, "superName"); it would first check class A for the field. Since A doesn't have it, the dowhile then moves on to it's superclass, which is B (not null so continue). B does have it, so it then returns the field. If B didn't have it, it would then check Object, then return null since Object doesn't have a superclass.

Alex Coleman
  • 7,216
  • 1
  • 22
  • 31
  • +1 for the method but you should never reassign a method parameter (`clazz` in that case). – aymeric Sep 18 '12 at 21:46
  • @aymeric Yeah, thanks, actually had it the way I edited it to now before, but changed it, wasn't thinking about it :) – Alex Coleman Sep 18 '12 at 22:05
  • But i know how to get all class field (also inherited) . But my problem is how to set all field values ? i found only one method to do this : field.set(Object obj, Object value), but this method can not allowed set inherited fields :/ – Łukasz Woźniczka Sep 19 '12 at 07:06
  • @Lukasz Wozniczka If you call `someFieldOfSuperClass.set(subClassOfClassWithField, value)` it will still work – Alex Coleman Sep 19 '12 at 20:38
6

You can use:

clazz.getSuperclass().getDeclaredField(s);

instead of (or in addition with some try-catch):

clazz.getDeclaredField(s);

EDIT:

To set the value for the superclass, use the following:

Field f = clazz.getSuperclass().getDeclaredField(s);
f.setAccessible(true); // Especially necessary if the field is not public
f.set(yourObject, theValue);
aymeric
  • 3,877
  • 2
  • 28
  • 42
1

get super class using Class.getSuperclass(). Then using super class, you can get it's fields.

Nandkumar Tekale
  • 16,024
  • 8
  • 58
  • 85
-1

It wont work with instance of A even if A extends from B , it is because private members are not accessible in sub classes . try changing the access of superName to protected and if it works ...

sharadendu sinha
  • 827
  • 4
  • 10