1

java中的反射问题

样本类

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

通过反射获取具有名称和参数的方法的方法

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

        }

    }

主程序

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

输出是:

一种

类 java.lang.String

类[C

整数

问题是下一个测试失败

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

ClassUtils 来自 org.apache.commons.lang3

寻找一个库来获取“[Ljava.lang.Character;” 而不是“[C”,因为它似乎 ClassUtils.primitivesToWrappers() 失败。

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

}
4

2 回答 2

2

失败的原因:

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

是 "[C" 表示 achar[]不是 a Character[]

你不能调用的原因ClassUtils.primitivesToWrappers()char[].classchar[]不是原始类型!

如果要将原始数组类映射到包装数组类,则:

  1. 用于Class.isArray()测试类型是否为数组
  2. 用于Class.getComponentType()获取基本类型
  3. 如果基本类型是原始的,则映射它。
  4. Arrays.newInstance(baseType, ...)通过使用创建一个数组然后调用getClass()它来创建映射基类型的数组类型。
于 2016-04-25T14:15:55.107 回答
1

恐怕您的问题不仅在primitivesToWrappers.

也不getMatchingAccessibleMethod如我所料:

在 Java 中,我可以调用:

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

这会导致 Java 中的编译错误:

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

但在 MethodUtils 测试中:

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

输出是(我希望 m2 和 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)

我将您的问题类修改为:

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; }
}
于 2016-04-25T15:15:15.407 回答