2

I have a class which has an interface as member

Class A {
    IProp property;
}

At runtime we assign property with one of the concrete classes implementing IProp. Say,

A a = new A();
a.property = new IPropImpl();

Now if I have object a, I get the fields using reflection :

Field[] fields = a.getDeclaredFields();

But for field property, the type is returned as IProp. I want to get the concrete type which was assigned to it. ( There maybe multiple concrete types. I want to get the one which is assigned to the field).

Can anyone help me out ?

Aneesh
  • 1,703
  • 3
  • 24
  • 34
  • 1
    You can use `instanceOf` on the field to test which is the implementation. I'm afraid that the only way to do that directly is changing `property` type to the implementation, which is not what you want. – Narmer Aug 26 '14 at 10:27

2 Answers2

3

getDeclaredFields() (or any other method of java.lang.Class for that matter) returns the compile-time data that's available for the class - it cannot return data based on a specific instance you're using.

What you could do is simply retrieve the instance you're holding and query its type:

System.out.println(a.property.getClass());

EDIT:

To address the comments, this can also be done by reflection, but would still have to address a specific instance:

for (Field f : a.getClass().getDeclaredFields()) {
    Class<?> cls = f.get(a).getClass();
    System.out.println
        (f.getName() + " is set with a concrete class of " + cls.getName());
}
Mureinik
  • 297,002
  • 52
  • 306
  • 350
2

You can use instanceOf on the field to test which is the implementation. I'm afraid that the only way to do that directly is changing property type to the implementation, which is not what you want.

The code would be:

IProp property = null;
try {
    property = (IProp) A.class.getDeclaredField("property").get(a);
} catch (IllegalArgumentException | IllegalAccessException
        | NoSuchFieldException | SecurityException e) {
    e.printStackTrace();
}
if(property instanceof IPropImpl){
    //do something
}else if(property instanceof IPropImpl2){
    //do something else
}

EDIT

If you want to get programmatically all implementing classes of a specific interface which are already instantiated you can do it with the Reflection library

new Reflections("my.package").getSubTypesOf(MyInterface.class)

Else if you are using Eclipse click on the interface name, IProp, and press CTRL + T. It will show all implementing classes for the interface in workspace.

Community
  • 1
  • 1
Narmer
  • 1,414
  • 7
  • 16
  • 1
    Problem with this approach is I really don't know what classes implement the interface. Is there any way to get the list of classes implementing a particular interface ? – Aneesh Aug 26 '14 at 10:36