Search code examples
javareflectionapache-commons-lang3

char[] to full quantified name of java class for method parameter


Problem with reflectiion in java

SampleClass

Class Question{
        public  int a   ( String a, char[] c,int b) { return  b; }    
}

Method to get method with name and parameters via reflection

 public Method getMethodWithParams(Class<?> klasa, String methodName, Class<?>[] params) throws
            SecurityException, NoSuchMethodException {
       Class<?>[] primitivesToWrappers =
                  ClassUtils.primitivesToWrappers(params);
        Method publicMethod = MethodUtils.getMatchingAccessibleMethod(klasa,
                                                                      methodName,
                                                                      primitivesToWrappers );
        System.out.println(publicMethod.toGenericString());

        return publicMethod;
    }

 private void printParams(Type[] types) throws ClassNotFoundException {

        for (Type genericParameterType : types) {
            System.out.println(genericParameterType.toString());

        }

    }

Main Program

Question cls = new Question();
    Class<?>[] paramString = new Class<?>[3];
            paramString[0] = String.class;
            paramString[1] = char[].class;
            paramString[2] = int.class;
     Method methodParams1 = getMethodParams(cls.getClass(),"a", paramString);
            System.out.println(methodParams1.getName());
            Type[] genericTypes = methodParams1.getParameterTypes();
            printParams(genericTypes);

output is:

a

class java.lang.String

class [C

int

Problem is that next test fails

Character testCharacterObjArray = new Character[]
Class<?> aClass = ClassUtils.getClass("[C", true);
Assert.assertEquals(testCharacterObjArray.getClass(), aClass);

ClassUtils is from org.apache.commons.lang3

Looking for a library to get "[Ljava.lang.Character;" instead of "[C", since it appears ClassUtils.primitivesToWrappers() fails.

Solution based on stephen:

public Class<?> convertStringToClass(String str) throws
        ClassNotFoundException {
    Class<?> aClass = ClassUtils.getClass(str, true);

    if (aClass.isArray()) {

        Class<?> primitiveToWrapper =
                 ClassUtils.primitiveToWrapper(aClass.getComponentType());
        Object newInstance = Array.newInstance(primitiveToWrapper, 0);
        System.out.println("****" + newInstance.getClass().getName());
        return ClassUtils.
                getClass(newInstance.getClass().getName(), true);
    }
    else {
        return ClassUtils.primitiveToWrapper(aClass);
    }

}

Solution

  • The reason that this fails:

    Character[] testCharacterObjArray = new Character[]
    Class<?> aClass = ClassUtils.getClass("[C", true);
    Assert.assertSame(testCharacterObjArray.getClass(), aClass);
    

    is that "[C" denotes a char[] not a Character[].

    The reason that you can't call ClassUtils.primitivesToWrappers() on char[].class is that that char[] is not a primitive type!

    If you want to map an array-of-primitive class to an array-of-wrapper class, then:

    1. Use Class.isArray() to test if the type is an array
    2. Use Class.getComponentType() to get the base type
    3. If the base type is primitive, map it.
    4. Create the array type of the mapped base type by using Arrays.newInstance(baseType, ...) to create an array and then call getClass() on it.