0

I have Interface:

public interface Car{
    public void drive();
}

Class which implements Car:

public class SuperCar implements Car{
    @Override
    public void drive(){

    }
}

And Class which uses Car as a method argument

public class CarDealer{
    public void sellCar( Car car)
}

I wan't to invoke sellCar method using getDeclaredMethod with SuperCar as a argument, but it doesn't find it because of different type of arguments( Car vs SuperCar)

public sellCarTest(){
    SuperCar superCar = new SuperCar();
    CarDealer carDealer = new CarDealer();
    Class dealer = CarDealer.class;
    Class[] args = Class[1];
    args[0] = superCar.getClass();
    Method m = dealer.getDeclaredMethod("sellCar", args);
    m.setAccessible(true);
    m.invoke(carDealer, superCar);
}

EDIT

Actually I've seen piece of code pasted in accepted answer, but it still didn't gave me correct answer.

I've found my answer here Testing private method using power mock which return list of Integers

Community
  • 1
  • 1
nervosol
  • 1,295
  • 3
  • 24
  • 46

3 Answers3

1

If you see the java source code of Class class, you can see the way it compares the arguments given for getting a method

private static boolean arrayContentsEq(Object[] a1, Object[] a2) {
    if (a1 == null) {
        return a2 == null || a2.length == 0;
    }

    if (a2 == null) {
        return a1.length == 0;
    }

    if (a1.length != a2.length) {
        return false;
    }

    for (int i = 0; i < a1.length; i++) {
        if (a1[i] != a2[i]) {
            return false;
        }
    }

    return true;
}

You can quickly check that

    Object X = P.class;
    Object Y = Q.class;// Q implements P
    System.out.println(X == Y);

will always print false. So you will not find any method with such arguments

Shiva Kumar
  • 3,111
  • 1
  • 26
  • 34
0

Seems easy enough, just cast SuperCar to Car:

public sellCarTest(){
    **Car** superCar = new SuperCar();
    CarDealer carDealer = new CarDealer();
    // ... rest of the method
}
Davio
  • 4,609
  • 2
  • 31
  • 58
0

Class.get*Method() looks for methods with parameters of exactly the types you specify. It doesn't respect subtype relationships between the types you specify and the types of the formal parameters of the method; nor does it respect primitive/wrapper relationships, or primitive widening.

You might be able to get the behavior you need by using java.beans.Statement or java.beans.Expression.

pholser
  • 4,908
  • 1
  • 27
  • 37