2

small question about something I can't get my head around. I have the following:

public abstract class A 
{
  ...
}

and an extension of this class

public class B extends A
{
 ...
}

Now I have a class that looks like the following

public class DoStuff extends AbstractDoStuff
{
  public void doNiceStuff(B b)
  {
    ...
  }
}

It is this class' method I'm trying to invoke by reflection. However I'm trying to invoke this method from a package that is not aware of B and only knows about A. This is due to dependencies of the projects

So I have the following code that needs to find method doNiceStuff(B):

public abstract class AbstractDoStuff
{
  public static Method getGetterMethod(Class<? extends AbstractDoStuff> stuffClass) throws NoSuchMethodException
  {
    Method method = stuffClass.getDeclaredMethod("doNiceStuff", A.class)
    ...
  }
}

so the getDeclaredMethod should find doNiceStuff on class DoStuff but it seems that reflection isn't able to find the method using the superclass A.class. However I can't provide B.class there as the package doesn't know anything about the existence of B.

any idea if there is a way to fix this?

regards

Michael

2
  • You can always iterate over all methods of that class (you can get them by getDeclaredMethods()), compare methods name and check if its argument extends A class. Commented Sep 11, 2013 at 9:46
  • How is the declaration of the method doNiceStuff in AbstarctDoStuff? When you change the parameter then it is overloaded not ovverriden method. Commented Sep 11, 2013 at 9:46

1 Answer 1

2

You could use a bit more reflection to get it:

Method[] methods = stuffClass.getMethods(); 
for(Method m: methods) {
   if(m.getName().equals("doNiceStuff")) {
      Class<?> paramTypes = m.getParameterTypes();

      //condition on the desired parameter types comes here
      if(paramTypes.length==1 && A.class.isAssignableFrom(paramTypes[0]) {
        //we found it!
      }

   }
}

Why is isSuperClass() not good in this case?

Suppose we'd do it like this:

if (paramTypes.length == 1 && paramTypes[0].getSuperclass().equals(A.class)) {
...

This solution would be good for the class B, but what if we have a class C?

public class C extends B {


    public void doNiceStuff(C arg0) {
        //do nice stuff here
    }

}

This condition

paramTypes[0].getSuperclass().equals(A.class)

would be false! paramTypes[0].getSuperClass() is B.class, and is not equal to A.class...

Class.getMethods()

Returns an array containing Method objects reflecting all the public member methods of the class or interface represented by this Class object, including those declared by the class or interface and those inherited from superclasses and superinterfaces.

Class.isAssignableFrom()

Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter. It returns true if so; otherwise it returns false. If this Class object represents a primitive type, this method returns true if the specified Class parameter is exactly this Class object; otherwise it returns false. Specifically, this method tests whether the type represented by the specified Class parameter can be converted to the type represented by this Class object via an identity conversion or via a widening reference conversion. See The Java Language Specification, sections 5.1.1 and 5.1.4 , for details.

Recommended reading:

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks for the information ppeterka. Although this solution fits the problem, I'm wondering why it couldn't be done with something like Class<? extends A>. How come that java isn't capable of figuring out the hierarcy?
Look up type java type erasure. To be backwards compatible with Java <1.5, generics is more of a syntactic sugar. Very-very-very simplified: In runtime Class<X extends whatever> will just be used as Class...
I've looked at isAssignableFrom() and if I understand it correctly it is just the opposite of what I'm trying to achieve. I have the superclass and I want to know if there is a method in dostuff which parameterlist expects a subclass of A (it expects B). the assignableFrom should no about the subclass and expect the superclass as parameter
@user1554188 true, I got it the wrong way. Swapped it around.
this is perfect, helpful to other users as well by your extended explanation Thanks a lot
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.