3

我正在尝试编写一个通用方法,该方法将基于通过反射调用方法来散列对象列表。这个想法是调用者可以指定哪个方法将生成散列密钥。我的问题是我想避免使用 @SuppressWarnings("unchecked") 注释。所以本质上我想找到一种方法让method.invoke返回一个T2类型的对象而不是Object。提前感谢您的帮助。

public static <T1, T2> HashMap<T2, T1> hashFromList(
        List<T1> items_to_be_hashed,
        String method_name_to_use_to_generate_key) {
    HashMap<T2, T1> new_hashmap = new HashMap<>(items_to_be_hashed.size() + 5, 1);
    for (T1 object_to_be_hashed : items_to_be_hashed) {
        try {
            //Call the declared method for the key
            Method method = object_to_be_hashed.getClass().getDeclaredMethod(method_name_to_use_to_generate_key);
            @SuppressWarnings("unchecked")
            T2 key = (T2) method.invoke(object_to_be_hashed);
            new_hashmap.put(key, object_to_be_hashed);
        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException exception) {
            exception.printStackTrace();
        }
    }
    return new_hashmap;
}
4

2 回答 2

8

避免抑制警告并进行真正的强制转换(这会发现问题)的唯一方法是T2在执行时知道,您可以通过一个额外的参数来做到这一点:

... hashFromList(List<T1> itemsToHash,
                 String generationMethod,
                 Class<T2> clazzT2)

然后您可以使用Class.cast

T2 key = clazzT2.cast(method.invoke(objectToHash));
于 2013-02-22T11:45:48.937 回答
1

引入一个接口,该接口将为您返回一个密钥

// T1 = key, T2 = object type
public interface KeyGenerator<T1, T2> {
  T1 generateKey(T2 object);
}

并让您的密钥生成器实现该接口,然后您可以将标题更改为

public static <T1, T2> HashMap<T2, T1> hashFromList(
        List<T1> items_to_be_hashed,
        KeyGenerator<T2, T1> keyGenerator) {

并将代码更改为

        T2 key = keyGenerator.generateKey(object_to_be_hashed);

这也意味着您可以删除 NoSuchMethod 异常,因为您现在应该在对象上进行静态类型(但显然您仍然可以获得 NPE)

希望这有帮助;并且应该注意的是,通常反射并不总是放入代码中的好东西!明智地使用它:)

于 2013-02-22T11:45:53.313 回答