如何在Java中确定泛型方法中的类型?

时间:2012-03-26 09:19:09

标签: java generics instanceof

我想要一个方法,从之前解析的JSON对象中提取数据作为正确的类型。 JSONObject(rawdata)扩展了Map,所以看起来像这样:

private <Type> Type getValue(String key, Type def)
{
    if (!rawdata.containsKey(key)) return def;
    if (!(rawdata.get(key) instanceof Type)) return def;
    return (Type) rawdata.get(key);
}

instanceof显然会产生编译时错误。参数def是默认值,如果密钥不可用或类型错误,则返回参数。但def也可以为空,因此def.getClass()无效。

如何查看Map-entry的内容以获取正确的类型?

4 个答案:

答案 0 :(得分:7)

由于类型擦除,处理默认值为null的情况的唯一方法是让方法需要额外的Class类型的参数 - 这通常更好,因为它允许默认值为是所需类型的子类。

答案 1 :(得分:2)

你只需要检查空值(null将计为任何类型,如果这是不希望的行为,那么你还需要传入所需的类)。

private <T> T getValue(String key, T def)
{
    if (!rawdata.containsKey(key)) return def;

    Object value = rawdata.get(key);

    if (def == null) return (T) value; 
    // note that the above is inherently unsafe as we cannot 
    // guarantee that value is of type T

    // this if statement is the same as "value instanceOf Type"
    // is type safe, but not null safe
    if (def.getClass().isAssignableFrom(value.getClass())) {
        return (T) value;
    } else {
        return def;
    }
}

更安全的方法签名是:

private <T> T getValue(String key, T defaultValue, Class<T> defaultClass)

这样,即使默认值为null,我们也可以安全地检查类型匹配。

答案 2 :(得分:1)

在没有给出默认值的情况下,最好的选择是接受返回类型的Class对象。你可以重载函数,如:

private <T> T getValue(String key, Type defaultValue);

private <T> T getValue(String key, Class<T> type);

答案 3 :(得分:0)

或者你可以使用Joshua Bloch撰写的“Effective Java Second Edition”一书中的Typesafe Heterogeneous Container(THC)模式。

基本上,插入时将项目的类存储在地图中。检索时你会知道类型是一样的。

Map<Class, Map<String, Object>> rawData = ...