Java return 嵌套类型参数
Java return nested type parameters
我对 Java 的通用系统有疑问。
在我的程序中是列表的包装器,它应该有一个方法 return 它是内部列表:
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 和一个 returns 与 id 关联的 wrapper 列表的方法:
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;
}
在我看来,没有办法同时检查列表的类型和元素的类型。
编译器无法知道什么 return 类型与您传递的特定字符串相关联(不能使字符串类型安全)。
但是,您可以用类型安全的标记对象替换字符串:
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)
我对 Java 的通用系统有疑问。 在我的程序中是列表的包装器,它应该有一个方法 return 它是内部列表:
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 和一个 returns 与 id 关联的 wrapper 列表的方法:
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;
}
在我看来,没有办法同时检查列表的类型和元素的类型。
编译器无法知道什么 return 类型与您传递的特定字符串相关联(不能使字符串类型安全)。
但是,您可以用类型安全的标记对象替换字符串:
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)