我有一个以这种方式定义的泛型方法:
public <T> T processGeneric(..., Class<T> type){
//do something
}
我希望这种方法尽可能通用,因此任何类型都应该被接受。
它通常可以工作,只要传递的类型是一个对象,但泛型类本身呢? 例如:
HashMap<String, String> result;
processGeneric(..., HashMap<String, String>.class); //this does not work
我必须让一切工作的唯一方法是将结果声明为原始类型:
HashMap result;
result = processGeneric(..., HashMap.class); //this works but gives me a warning
但是......这真的是唯一的方法吗?
我正在使用Java-7。
答案 0 :(得分:2)
您可以(并且应该)避免以这种方式使用原始类型:
HashMap<String, Integer> result;
result = processGeneric(HashMap.class);
然而,您无法避免未经检查的强制转换(至少在不知道processGeneric
方法主体的详细信息的情况下)。唯一的选择是创建自己的类型,明确绑定HashMap
类型参数:
public class StringIntegerMap extends HashMap<String, Integer> {}
HashMap<String, Integer> result;
result = processGeneric(StringIntegerMap.class);
如果没有太多不同的通用参数,这可能是可以接受的。
一般记住,“原始类型”警告是邪恶的,必须尽可能避免。 “未经检查的施法”警告有时是必要的邪恶,如果你知道你在做什么就没关系。
答案 1 :(得分:1)
杰克逊在这种情况下有很好的例子:
HashMap<String, Integer> yourMap = new ObjectMapper().readValue(..., new TypeReference<HashMap<String, Integer>>() {});
的想法
文章中的代码:
public abstract class TypeReference<T> {
private final Type type;
private volatile Constructor<?> constructor;
protected TypeReference() {
Type superclass = getClass().getGenericSuperclass();
if (superclass instanceof Class) {
throw new RuntimeException("Missing type parameter.");
}
this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
}
/**
* Instantiates a new instance of {@code T} using the default, no-arg
* constructor.
*/
@SuppressWarnings("unchecked")
public T newInstance()
throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException, InstantiationException {
if (constructor == null) {
Class<?> rawType = type instanceof Class<?>
? (Class<?>) type
: (Class<?>) ((ParameterizedType) type).getRawType();
constructor = rawType.getConstructor();
}
return (T) constructor.newInstance();
}
/**
* Gets the referenced type.
*/
public Type getType() {
return this.type;
}
public static void main(String[] args) throws Exception {
List<String> l1 = new TypeReference<ArrayList<String>>() {}.newInstance();
List l2 = new TypeReference<ArrayList>() {}.newInstance();
}
}
答案 2 :(得分:0)
param类型是一个Class对象:
1,Class clazz = XXX.class;
2,Class clazz = Class.forName("xxx.xxx.xxx");
没有HashMap<String, String>.class
,或者您可以定义新类扩展它,然后可以使用'newClassName.class'代替它。