Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IllegalArgumentException when calling invoke method using Java Reflections

I have a class that has a method as follows :-

public void setCurrencyCode(List<String> newCurrencycode){
    this.currencycode = newCurrencycode;
}

I am using Java Relections to invoke this method as follows :-

try {
    List<String> value = new ArrayList<String>();
    value.add("GB");

    Class<?> clazz = Class.forName( "com.xxx.Currency" );
    Object obj = clazz.newInstance();
    Class param[] = { List.class };
    Method method = obj.getClass().getDeclaredMethod( "setCurrencyCode", param );
    method.invoke( value );
} catch(Exception e) {
    System.out.println( "Exception : " + e.getMessage() );
}

However, an exception is raised on the "invoke" call :- java.lang.IllegalArgumentException: object is not an instance of declaring class

Any ideas?

Thanks

Sarah

like image 933
Sarah Rushworth Avatar asked Dec 12 '22 11:12

Sarah Rushworth


2 Answers

You are not calling invoke() correctly: invoke() expects the target object as the first parameter, then the parameters to the method call as the following parameters (since java 1.5, it's a varargs parameter)

Try this:

try 
    {
        List<String> value = new ArrayList<String>();
        value.add("GB");

        Class<?> clazz = Class.forName( "com.xxx.Currency" );
        Object obj = clazz.newInstance();
        // Since java 1.5, you don't need Class[] for params: it's a varargs now 
        Method method = clazz.getDeclaredMethod( "setCurrencyCode", List.class ); // you already have a reference to the class - no need for obj.getClass()
        method.invoke( obj, value ); // invoke expects the target object, then the parameters
    }
    catch(Exception e)
    {
        System.out.println( "Exception : " + e.getMessage() );
    }
}
like image 144
Bohemian Avatar answered Dec 22 '22 00:12

Bohemian


This means that the value object you pass into invoke is not an instance of the class on which the method is defined. This is because the first argument of invoke is the object on which to make the call, and the subsequent arguments are the parameters to the invoked method. (In this case it looks like value needs to be an instance of com.xxx.Currency - which of course it isn't, because it's a List.)

Since you're calling a non-static method (and going to to trouble of creating a new instance), then for the reflective equivalent of obj.setCurrencyCode(value), at the end of your try block you'd need to call

method.invoke(obj, value)

instead of your current single one-arg call.

like image 42
Andrzej Doyle Avatar answered Dec 22 '22 00:12

Andrzej Doyle