File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes Passing an array into a vararg method (in Reflection API) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Passing an array into a vararg method (in Reflection API)" Watch "Passing an array into a vararg method (in Reflection API)" New topic
Author

Passing an array into a vararg method (in Reflection API)

Mark Vedder
Ranch Hand

Joined: Dec 17, 2003
Posts: 624

I working with the Java 1.5 implementation of Reflection API. I need to reflectively access a private method that takes a String array as a parameter:



I am using the getDeclaredMethod(String name, Class... parameterTypes) method to gain access. I have used this method many time before. However, I am running into a problem since my parameterType is an array. When I attempt the following:



I get a warning during compile time:

1 warning
Warning (55,1) non-varargs call of varargs method with inexact argument type for last parameter;
cast to java.lang.Object for a varargs call
cast to java.lang.Object[] for a non-varargs call and to suppress this warning


and an exception at runtime:

java.lang.IllegalArgumentException: wrong number of arguments
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method


Based on the warnings information, I have attempted to figure out the syntax to resolve this, but since I need a Class and not an Object for my vararg, I am not sure how to go about doing this. My Google searches have not found any suggestions.

Any suggestions or help with a way of doing this would be very much appreciated.
[ October 28, 2006: Message edited by: Mark Vedder ]
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

I don't believe it's the call to getDeclaredMethod() that's the problem -- I believe it's the call to invoke(), where the underlying method wants an Object[] (an array of arguments) and you're passing a String[], which is itself an Object[], and it is being misinterpreted as the list of arguments itself, rather than as a single element of that list. You'd get the same error for this code with a pre-Tiger compiler, too. You could cast the String[] to an Object, so it's properly interpreted as one element of a varargs; personally, I'd prefer

method.invoke(instance, new Object[] { args });

because I think it's less obscure (and of course it's what the other version would compile too, anyway.)


[Jess in Action][AskingGoodQuestions]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[EFH]: You could cast the String[] to an Object

That doesn't quite work. The problem is that what's needed is similar to an array of arrays. More precisely, it needs to be an array of Objects, one of which (the only one) is a String[]. Simply casting doesn't introduce the extra array level. But this works:

That should be equivalent to the code EFH gave (though we've used the name "args" differently), but neither is equivalent to simply casting the String[] to an Object[].
[ October 28, 2006: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Originally posted by Jim Yingst:

That doesn't work


Ah, yes it does, my friend. I didn't say cast to Object[] -- I said cast to Object. If you do that, the compiler doesn't "know" the argument is an array anymore, so it wraps it in a one-element array to pass as the varargs parameter.

You kind of proved my point about that being obscure, though -- if it's not obvious to Jim, then I think it's too obscure to use in normal code!
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Ah, thanks. Oopsie. That's what I get for reading too quickly. I'd been about to post a solution independently, saw you'd just posted, and quickly scanned to see how they related. Too quickly, it seems.
Mark Vedder
Ranch Hand

Joined: Dec 17, 2003
Posts: 624

Gentlemen,

Thanks so much for you input and successfully solving my issue.

Originally posted by Ernest Friedman-Hill:
I don't believe it's the call to getDeclaredMethod() that's the problem -- I believe it's the call to invoke()...

You are 100% correct of course... and had I paid closer attention to the line number shown in the compile warning and in the stack trace, I would have seen that. I swear that when I did that last night, the line number reported was that of the getDeclaredMethod(). Chalk it up to being too mentally fatigued after a 10-hour coding session I guess. :roll: At least that is my excuse for making such a careless mistake... not that I would necessarily have solved the issue, but at least I would have been looking in the right place as I was trying to cast the getDeclaredMethod()'s vararg to an Object.

I took Jim's suggestion, along with a heavy dose of commenting, to keep the code as non-obscure as possible.

Again, I thank you both for your prompt and detailed replies. I consistently learn many things from each of you, and others here at the ranch, through your many quality posts. Have a happy Halloween!
[ October 29, 2006: Message edited by: Mark Vedder ]
supriya riya
Ranch Hand

Joined: Feb 23, 2009
Posts: 41
Hi,
i am getting same error arguments type mismatch my set method has a String array.
and my value is Object which has a String seprated by ","
Please help.
Thanks
Code is given below for reference.


supriya riya
Ranch Hand

Joined: Feb 23, 2009
Posts: 41
"my set method means"

method.invoke calls a setter method with argument as string array
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19783
    
  20

Obviously, value is a String, not a String[] or Object[].

By the way, for the above old posts, it's not necessary to create a new one-element Object[]. Explicitly casting the String[] to Object will also work:
This will cause the String[] to be seen as one single argument instead of an array with all arguments.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Vinay Jaasti
Greenhorn

Joined: May 28, 2012
Posts: 2
Use method.invoke(instance, new Object[]{args});
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40034
    
  28
Welcome to the Ranch Vinay Jaasti

That will create a 1‑element Object array whose member is the array args.
Vinay Jaasti
Greenhorn

Joined: May 28, 2012
Posts: 2
Yes..

to get rid of Argument Mismatch exception in reflection,

http://yourmitra.wordpress.com/2008/09/26/using-java-reflection-to-invoke-a-method-with-array-parameters/
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40034
    
  28
Thank you
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Passing an array into a vararg method (in Reflection API)