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

出力は次のとおりです。

a

クラス 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;」を取得するライブラリを探しています。ClassUtils.primitivesToWrappers() が失敗するように見えるため、「[C」の代わりに。

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" は a char[]not 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 については null ではないことが期待されます):

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)

Question クラスを次のように変更しました。

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 に答える