在运行时检查类是否具有使用泛型的特定构造函数

Ben*_*ris 6 java generics reflection constructor introspection

大家好:)我正在尝试在类中选择正确的构造函数.这是代码:

Constructor[] constructors = targetClass.getConstructors();
Constructor goodConstructor = null;
for (Constructor constructor : constructors) {
    Class[] parameterTypes = constructor.getParameterTypes();
    if (parameterTypes.length = 1 && parameterTypes[0].equals(Map.class)) {//here
        goodConstructor = constructor;
    }
}
Run Code Online (Sandbox Code Playgroud)

我想切换Map.classMap<String, String>.class.我依稀记得泛型仅用于编译时,所以这就是编译器抱怨的原因.如何在运行时检查该类是否具有正确的构造函数?

最好的祝福

Mar*_*ers 8

您想要使用getGenericParameterTypes():

public class FindConstructor {

    public static void main(String[] args) throws IOException {
        for (Constructor<?> constructor : MyClass.class.getConstructors()) {
            Type[] parameterTypes = constructor.getGenericParameterTypes();
            if (parameterTypes.length == 1 && parameterTypes[0] instanceof ParameterizedType) {
                ParameterizedType parameterizedArg = (ParameterizedType) parameterTypes[0];
                if (parameterizedArg.getRawType() != Map.class) {
                    continue;
                }

                if (parameterizedArg.getActualTypeArguments()[0] != String.class) {
                    continue;
                }

                if (parameterizedArg.getActualTypeArguments()[1] != String.class) {
                    continue;
                }
            }
            System.out.println("found constructor " + constructor);
        }
    }
}

class MyClass {
    public MyClass(Map<String, String> map) {
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果你改变MyClass()采取Map<String, Integer>它将不再匹配.

使用Guava's会变得更容易TypeToken,它使用匿名类来创建Type我们可以比较的参数化.

Type mapStringString = new TypeToken<Map<String, String>>(){}.getType();
for (Constructor<?> constructor : MyClass.class.getConstructors()) {
    Type[] parameterTypes = constructor.getGenericParameterTypes();
    if (parameterTypes.length == 1 && parameterTypes[0].equals(mapStringString)) {
        System.out.println("found constructor " + constructor);
    }
}
Run Code Online (Sandbox Code Playgroud)