我想定义一个泛型参数,它应该扩展Map或Collection,但我不知道该怎么做:
public <T> void test(T t) {}
我可以把它写成:
public <T extends Map> void test(T t) {}
或
public <T extends Collection> void test(T t) {}
但我不知道是否可以让T在单一方法中扩展Map或Collection。
答案 0 :(得分:5)
简答:不。
您打算如何处理方法中的t
参数?由于Map
和Collection
只有Object
作为常用超类型,因此t
上可以调用的唯一方法是Object
上的方法。 (甚至两个接口上的方法,例如size()
,也会被编译器拒绝。)
考虑到这一点,在这种情况下你有什么理由不能重载方法吗?也就是说,为每个所需的参数类型定义一个实现:
public void test(Map<?,?> t) { ... }
public void test(Collection<?> t) { ... }
如果您不想出于某种原因这样做,那么您似乎可以同样声明方法以获取Object
并执行类的运行时类型检查。这在语义上是等价的,因为你必须转换为调用Map
或Collection
- 特定方法,尽管它确实意味着类型检查是在编译时而不是运行时完成的。虽然Java的类型系统不允许你表达这种联合类型的依赖,所以我没有看到任何其他的替代方案。
答案 1 :(得分:3)
不可能,但您可以创建两个单独的方法:
public <T extends Map> void test(T t) {
// do the map part
}
public <T extends Collection> void test(T t) {
// do the collection part
}
如果你想在处理方法中混合它们,你也可以这样写:
private void mixedTest(Object t) {
if (t instanceof Map) {
// map part
} else if (t instanceof Collection) {
// collection part
} else {
throw new RuntimeException("Unknown object");
}
}
并致电:
public <T extends Map> void test(T t) {
mixedTest(t);
}
public <T extends Collection> void test(T t) {
mixedTest(t);
}
但我不确定它会导致一个不错的代码。我会坚持使用不同类型对象的不同实现的第一部分。
答案 2 :(得分:3)
怎么样?
public <T extends Map> void test(Map t) {}
和
public <T extends Collection> void test(Collection t) {}
...然后让Java选择正确使用的那个?