【问题标题】:Issue using Generics and Parameterized List使用泛型和参数化列表的问题
【发布时间】:2012-07-24 18:40:53
【问题描述】:

我创建了以下测试类:

public class GenericTest {

    public static class A implements Serializable {

    }

    public static class B implements Serializable {

    }

    public static void main(String[] args) {
        // Error: Type mismatch: cannot convert from List<capture#1-of ? extends Serializable> to List<GenericTest.A>
        //List<A> aList = getInfo().get("A");
        //List<B> BList = getInfo().get("B");

        // Warning: Type safety: Unchecked cast from List<capture#1-of ? extends Serializable> to List<GenericTest.A>
        List<A> aList = (List<A>)getInfo().get("A");
        List<B> BList = (List<B>)getInfo().get("B");
    }

    public static Map<String, List<? extends Serializable>> getInfo() {
        Map<String, List<? extends Serializable>> infoMap = new HashMap<String, List<? extends Serializable>>();

        List<A> aList = new ArrayList<A>();
        List<B> bList = new ArrayList<B>();

        try {
            aList.add(new A());
            infoMap.put("A", aList);

            bList.add(new B());
            infoMap.put("B", bList);
        }
        catch(Exception e) {
            e.printStackTrace();
        }

        return infoMap;
    }    
}

有没有更好的方法来避免投射和抑制未经检查的警告?有人告诉我,使用强制转换几乎一开始就违背了使用泛型的目的。这样做有问题,还是“更安全”的方法?

【问题讨论】:

  • 您不应该在您的方法的返回类型中使用通配符?。这意味着你的方法返回了一些未知的东西。

标签: java list generics casting parameterized


【解决方案1】:

您可以尝试这样做。您仍然需要在 getList 方法中抑制警告,但如果您只使用 addToMap 方法添加列表,编译器可以正确检查添加的列表是否与第一个参数中使用的类类型相同。也可以在谷歌上搜索超级类型令牌。

public static void main(String[] args) {
    List<A> aList = new ArrayList<A>();
    aList.add(new A());
    List<B> bList = new ArrayList<B>();
    bList.add(new B());
    addToMap(A.class,aList);
    addToMap(B.class,bList);        

    List<A> aListFromMap = getList(A.class);
    List<B> bListFromMap = getList(B.class);
}



private static Map<Class<?>,Object> infoMap = new HashMap<Class<?>,Object>();



public static <T extends Serializable> void addToMap(Class<T> key, List<T> value) {
    infoMap.put(key,value);
}


public static <T extends Serializable> List<T> getList(Class<T> key) {
    return (List<T>)(infoMap.get(key));
} 

【讨论】:

    【解决方案2】:

    不,没有办法解决这种情况。您有一个包含两种值的映射(这称为 heterogeneous 映射)并且类型系统无法表达这一点。您必须在没有类型安全的情况下沮丧。要么这样,要么完全重新设计以将这两种对象保持在两个独立的结构中。

    【讨论】:

    • 无论如何,如果您只想使用泛型类型“Serializable”并抑制警告,您可以将类型列表更改为:List aList = getInfo().get("A");列表 extends Serializable> BList = getInfo().get("B");
    猜你喜欢
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    相关资源
    最近更新 更多