Java返回嵌套类型参数

问题描述 投票:0回答:1

我的Java通用系统有问题。在我的程序中是列表的包装器,应该有一个方法来返回它的内部列表:

public class Wrapper<T, S extends List<T>> {

    private S list;

    public Wrapper(S list) {
        this.list = list;
    }

    public S get() {
        return list;
    }
}

然后有一个Context,它包含一个带有不同Wrappers的Map和一个返回与id关联的包装器列表的方法:

public class Context {

    private Map<String, Wrapper> map;

    public Wrappers() {
        map.put("a", new Wrapper(ArrayList<String>());
        map.put("b", new Wrapper(LinkedList<Integer>());
    }

    public <T, S extends List<T>> S getList(String id) {
        return map.get(id).get();
    }
}

现在,当我调用getList()时,我想要一个编译器警告或至少一种方法来在抛出ClassCastException之前实现错误。

public class Receiver {

    public doSomething() {
        Context c  = new Context();
        c.createWrappers();

        // Ok
        ArrayList<String> list1 = c.getList("a");
        LinkedList<Integer> list2 = c.getList("b");

        // Compiler error or some way do check in getList().
        ArrayList<Integer> list3 = c.getList("a");
        LinkedList<String> list4 = c.getList("b");
    }
}

我实际上已经尝试了很多东西,例如将Wrapper定义更改为:

public class Wrapper<T, S extends List>

但是当我想实现get()函数时遇到问题我可以像这样定义函数:

public List<T> get() {
    return list;
}

或者像这样

public S get() {
    return list;
}

在第一个例子中,仍然可以这样做。

public doSomething() {
    //...
    LinkedList<String> list = c.getList("a");
}

在第二个例子中,可以这样做。

public doSomething() {
    //...
    ArrayList<Integer> list = c.getList("a");
}

有没有办法以这样的方式定义get方法?

public S<T> get() {
    return list;
}

在我看来,无法同时检查列表的类型和元素的类型。

java generics classcastexception
1个回答
0
投票

编译器无法知道哪个返回类型与您传递的特定字符串相关联(字符串不能使其成为类型安全的)。

但是,您可以使用类型安全的标记对象替换字符串:

class ListId<T> {
    public ListId(string name) { ... }

    public static final ListId<ArrayList<String>> A = new ListId<>("a");
    public static final ListId<LinkedList<Integer>> B = new ListId<>("b");
}

public T getList<T>(ListId<T> id)
© www.soinside.com 2019 - 2024. All rights reserved.