我正在尝试编写一个通用方法,该方法将基于通过反射调用方法来散列对象列表。其思想是,调用者可以指定哪种方法将生成用于哈希的密钥。我的问题是,我想避免@SuppressWarnings("未选中")注释。所以本质上,我想找到一种方法来获取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;
}
避免抑制警告并进行true强制转换(这会引发问题)的唯一方法是在执行时知道T2
,这可以通过一个额外的参数来实现:
... hashFromList(List<T1> itemsToHash,
String generationMethod,
Class<T2> clazzT2)
然后可以使用Class.cast
:
T2 key = clazzT2.cast(method.invoke(objectToHash));
引入一个接口,该接口将为返回密钥
// 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)
希望这能有所帮助;需要注意的是,通常情况下,将反射放入代码中并不总是一件好事!明智地使用它:)