如何定义应扩展Map或Collection的泛型参数?

时间:2012-05-09 08:39:40

标签: java generics

我想定义一个泛型参数,它应该扩展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。

3 个答案:

答案 0 :(得分:5)

简答:不。

您打算如何处理方法中的t参数?由于MapCollection只有Object作为常用超类型,因此t上可以调用的唯一方法是Object上的方法。 (甚至两个接口上的方法,例如size(),也会被编译器拒绝。)

考虑到这一点,在这种情况下你有什么理由不能重载方法吗?也就是说,为每个所需的参数类型定义一个实现:

public void test(Map<?,?> t) { ... }
public void test(Collection<?> t) { ... }

如果您不想出于某种原因这样做,那么您似乎可以同样声明方法以获取Object并执行类的运行时类型检查。这在语义上是等价的,因为你必须转换为调用MapCollection - 特定方法,尽管它确实意味着类型检查是在编译时而不是运行时完成的。虽然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选择正确使用的那个?