如何将参数指定为通用类型,例如List / Map <t>?

时间:2015-10-26 07:05:17

标签: java generics

我有一个以这种方式定义的泛型方法:

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。

3 个答案:

答案 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>>() {});

基于super type tokens

的想法

文章中的代码:

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'代替它。

相关问题