Я знаю всевозможные контр-интуитивные свойства общих типов 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 должна быть четко определена - я не могу думать о какой-либо потере безопасности типа, разрешая пересечение двух типов, а не только одного. Я уверен, что есть объяснение. Кто-нибудь знает, что это такое?