简体   繁体   中英

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);
    }

}

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.

I'm afraid that your problem is not only in primitivesToWrappers .

Also getMatchingAccessibleMethod doesn't as I would expect:

In Java I can call:

    new Question().foo("a", new char[] {'a'}, 1);
    new Question().foo("b", new char[] {'b'}, Integer.valueOf(2));

    new Question().bar("c", new char[] {'c'}, 3);
    new Question().bar("d", new char[] {'d'}, Integer.valueOf(4));

this results in compilation error in Java:

    new Question().foo("b", new char[] {'b'}, Integer.valueOf(2));

but in MethodUtils tests:

    Method m1 = MethodUtils.getMatchingAccessibleMethod(Question.class, "foo", String.class, char[].class, int.class);
    System.out.println("m1:" + m1);
    Method m2 = MethodUtils.getMatchingAccessibleMethod(Question.class, "foo", String.class, char[].class, Integer.class);
    System.out.println("m2: " + m2);
    Method m3 = MethodUtils.getMatchingAccessibleMethod(Question.class, "foo", String.class, Character[].class, Integer.class);
    System.out.println("m3: " + m3);

    Method mb1 = MethodUtils.getMatchingAccessibleMethod(Question.class, "bar", String.class, char[].class, int.class);
    System.out.println("mb1: " +mb1);
    Method mb2 = MethodUtils.getMatchingAccessibleMethod(Question.class, "bar", String.class, char[].class, Integer.class);
    System.out.println("mb2:" + mb2);

the output is (and I'd expect not null for m2 and mb1):

m1: public int LangTest$Question.foo(java.lang.String,char[],int)
m2: null
m3: null
mb1: null
mb2: public int LangTest$Question.bar(java.lang.String,char[],java.lang.Integer)

I modified your Question class to:

static class Question {
    public  int foo( String a, char[] c,int b) { return  b; }
    public  int bar( String a, char[] c,Integer b) { return  b; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM