我知道Java的泛型类型有各种反直觉的属性。以下是其中之一,我不太理解,希望有人能够解释一下。在为类或接口指定类型参数时,您可以将其限制为必须实现多个接口,如public class Foo<T extends InterfaceA & InterfaceB>
。然而,如果您正在实例化一个实际对象,则此方法不再适用。 List<? extends InterfaceA>
是可以的,但 List<? extends InterfaceA & InterfaceB>
无法编译。请考虑以下完整代码片段:
import java.util.List;
public class Test {
static interface A {
public int getSomething();
}
static interface B {
public int getSomethingElse();
}
static class AandB implements A, B {
public int getSomething() { return 1; }
public int getSomethingElse() { return 2; }
}
// Notice the multiple bounds here. This works.
static class AandBList<T extends A & B> {
List<T> list;
public List<T> getList() { return list; }
}
public static void main(String [] args) {
AandBList<AandB> foo = new AandBList<AandB>(); // This works fine!
foo.getList().add(new AandB());
List<? extends A> bar = new LinkedList<AandB>(); // This is fine too
// This last one fails to compile!
List<? extends A & B> foobar = new LinkedList<AandB>();
}
}
看起来bar
的语义应该是明确定义的——我想不出允许两种类型交集而不仅仅是一种会导致类型安全丢失的情况。但我肯定有解释。有人知道是什么吗?
&
字符是表示多个边界的标准方式。 "class AandBList<T extends A & B>
"只是语言的工作方式,尽管我同意使用<T extends A, B>
会更直观,以匹配public interface A extends C,D
。在泛型类型的限制中,无论是接口还是类,都使用extends
。虽然很令人困惑,但这就是当前的情况。 - Adrian Petrescu