2

I am trying to understand how reflection works with Nested objects:

here is ClassA

public class ClassA {

    Integer A;
    Integer B;
    List<ClassB> C;

    public Integer getA() {
        return A;
    }
    public void setA(Integer a) {
        A = a;
    }
    public Integer getB() {
        return B;
    }
    public void setB(Integer b) {
        B = b;
    }
    public List<ClassB> getC() {
        return C;
    }
    public void setC(List<ClassB> c) {
        C = c;
    }


}

ClassB:

public class ClassB {

    int a ;
    int b;

    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
    public int getB() {
        return b;
    }
    public void setB(int b) {
        this.b = b;
    }


}

And i am trying to access the fields like this:

 public static void main(String[] args){
    ClassA classA=new ClassA();
       Field[] fields =classA.getClass().getDeclaredFields();
       for (Field field : fields) {
           System.out.println(field.getName());
       }
   }

Problem: i want to access the fields of ClassB , i am trying to do something like this :

fields[2].getType().getDeclaredFields();

but getType() returns interface java.util.List which is true but i am aiming for the members/fields of ClassB

Then i tried : fields[2].getGenericType() which returns java.util.List and in Debug mode i can see it returns ParameterizedTypeImpl but i am not declare and fetch actualTypeArguments.

Somehow it gives compilation problems when i declare parameterizedTypeImpl.

ParameterizedTypeImpl impl=fields[2].getGenericType();

ParameterizedTypeImpl cannot be resolved to a type

See the attached picture. enter image description here

Any pointers or help would be highly appreciated.

UPDATE:

I found the solution :

  for (Field field : fields) {
           if(field.getType().getTypeName().equalsIgnoreCase("java.util.List")){
                  ParameterizedType impl=(ParameterizedType) field .getGenericType();
                  String nameOfClass=impl.getActualTypeArguments()[0].getTypeName();
           }

Thanks for your help guys.

lesnar
  • 2,400
  • 7
  • 41
  • 72
  • Just a quick review, you are accessing the `List`, you still need to iterate it to get the instances of `ClassB`. – AxelH Feb 20 '17 at 06:59
  • @AxelH yes that is clear to me. thanks for pointing out though. – lesnar Feb 20 '17 at 07:02
  • 1
    Please don't say "Somehow it gives compilation problems". If it gives you an error at compile time, please show the code you tried and tell us what the error is. Don't hide important information from us. – ajb Feb 20 '17 at 07:04
  • Maybe this post can help http://stackoverflow.com/questions/1901164/get-type-of-a-generic-parameter-in-java-with-reflection – Massimo Petrus Feb 20 '17 at 07:08
  • @ajb i have updated the code. It is just saying ,ParameterizedTypeImpl cannot be resolved to a type – lesnar Feb 20 '17 at 07:09
  • 1
    Just use the interface `ParameterizedType`. – shmosel Feb 20 '17 at 07:15
  • 1
    What shmosel said. `ParameterizedType` is the interface that's documented in the javadoc, and it provides all the methods. `ParameterizedTypeImpl` is a class they use internally to implement the interface. It's not intended for you to access that class, since it's internal, although you can see the class name in a debugger or by using `getClass()`. – ajb Feb 20 '17 at 14:12

1 Answers1

2
 ClassA classA=new ClassA();
       Field[] fields =classA.getClass().getDeclaredFields();
       for (Field field : fields) {
           if (Collection.class.isAssignableFrom(field.getType())){
               System.out.println(field.getName());//you can remove this as per requirement
               Class<?> c1 = (Class<?>) ((((ParameterizedType) field.getGenericType()).getActualTypeArguments())[0]);

                Field[] fieldsInner = c1.getDeclaredFields();
                for (Field fieldInner : fieldsInner) {
                    System.out.println(fieldInner.getName());

           }
           else{
           System.out.println(field.getName());}

       }
skY
  • 111
  • 7