2

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

4

3 回答 3

5

简短的回答:没有。

您打算如何处理t方法中的参数?由于Mapand Collectionhave 仅Object作为它们的共同超类型,因此您可以调用的唯一方法t将是那些 on Object。(即使两个接口上的方法,例如size(),也会被编译器拒绝。)

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

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

如果您出于某种原因不想这样做,那么您似乎同样可以声明要采用的方法Object并执行该类的运行时类型检查。这在语义上是等效的,因为无论如何您都必须强制转换为 callMapCollection-specific 方法,尽管这确实意味着类型检查是在编译时而不是运行时完成的。Java 的类型系统不允许您表达这种联合类型的依赖关系,所以我看不到任何其他选择。

于 2012-05-09T08:45:38.140 回答
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);
}

但我不确定它是否会导致一个很好的代码。对于不同类型的对象,我会坚持使用不同实现的第一部分。

于 2012-05-09T08:44:44.253 回答
3

关于什么

public <T extends Map> void test(Map t) {}

public <T extends Collection> void test(Collection t) {}

...然后让 Java 选择正确的使用?

于 2012-05-09T08:45:39.497 回答