views:

877

answers:

3

I have an object m of class Method. I invoked m.getParameterTypes() to create an array params of the method's parameters. I also have an array arr of Objects. I wanted to check if the objects in arr are of the same types as the types in params (and in the same order). What I did was to create an array classes which includes the class of each object in arr. Then I tried to compare classes with params. Turns out they can never be equal because the classes in the classes array are in the format of 'java.lang.String' and the parameters in the param array are in the format of 'String'. How can I compare the arrays? How can I change the format of one of them?

A: 

If you are doing this sort of comparison you should use the fully qualified name ('java.lang.String' type) to ensure the match is really correct (since two classes can have the same "simple" name and be from different packages).

Can you provide the code you used, so we can guide you on what needs to be changed to obtain the fully qualified names?

Method getParameterTypes() returns a Class[], so each element is a Class. You can call either getCanonicalName() (or getName() in some circumstances, see the javadoc for Class) to get the fully qualified name.

For the array of objects, you can call object.getClass().getCanonicalName() to get the equivalent.

EDIT: Jon Skeet's reply is a better approach where you don't compare names at all, but instead use the Class isInstance() method to check that the Class is compatible.

fd
"Jon Skeet's reply is a better approach..." Ahh, how many times has that happened...
Bill K
+6  A: 

getParameterTypes() returns a Class<?>[] whereas the actual arguments themselves will be objects (so you'll have an Object[]). To check that the arguments are valid, you could use:

if (parameterTypes.length != arr.length) {
  // Invalid: wrong number of arguments
}

for (int i=0; i < parameterTypes.length; i++) {
  if (arr[i] == null && parameterTypes[i].isPrimitive()) {
    // Invalid: can't pass null for a primitive parameter
  } else if (arr[i] != null && !parameterTypes[i].isInstance(arr[i])) {
     // Invalid: invalid argument type
  } else {
     // Valid
  }
}

(Do whatever you need to do for the valid/invalid cases, of course.)

Jon Skeet
Good solution. `...isInstance(arr[i])` will return false if passed null so no need to test `arr[i]` first. Also don't forget to verify arr.length == parameterTypes.length or you could get IndexOutOfBoundsExceptions.
Chadwick
The point about checking for nullity is precisely *because* isInstance will return false - it's not an error to pass in null if it's a reference type parameter. I'll add the length checking though...
Jon Skeet
A: 

Instead of you checking if the method's parameters are compatible with your Object array, why not let Class.getMethod() do it for you? What I mean is, why not do something like this:

Class[] classes = new Class[myArr.length];
for (int i=0; i<myArr.length; i++) {
    classes[i] = myArr[i].getClass();
}

Method m = YouMethodsClass.class.getMethod("methodName", classes);

Wouldn't that work for you?

antrix