6

Hello all :) I'm trying to chose the right constructor in a class. Here is the code:

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

I want to switch from Map.class to Map<String, String>.class. I vaguely remember that generics are for compile time only, so this is why the compiler is complaining. How can I check at runtime that the class has the right constructor?

Best regards

4

2 回答 2

9

您想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) {
    }
}

现在,如果您更改MyClass()为采取 aMap<String, Integer>它将不再匹配。

使用 Guava 变得更容易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);
    }
}
于 2013-04-17T15:26:43.533 回答
0

类在 java 中不是这样工作的。类不能在运行时参数化;只有实例。对于 Map 的每个通用实现,只有一个Map.class,而不是(您似乎已经假设)一个单独的类。以下代码可能有助于澄清这一点:

    Map<String,String> m1 = new HashMap<>();
    Map<Object,Long> m2 = new HashMap<>();

    System.out.println(m1.getClass() == m2.getClass());//prints "true"
于 2013-04-17T15:33:16.013 回答