Ich weiß, dass es alle möglichen kontraintuitiven Eigenschaften der generischen Typen von Java gibt. Hier ist eine, die ich nicht verstehe und von der ich hoffe, dass sie mir jemand erklären kann. Wenn Sie einen Typparameter für eine Klasse oder Schnittstelle angeben, können Sie ihn so binden, dass mehrere Schnittstellen mit implementiert werden müssen public class Foo<T extends InterfaceA & InterfaceB>
. Wenn Sie jedoch ein tatsächliches Objekt instanziieren, funktioniert dies nicht mehr. List<? extends InterfaceA>
ist in Ordnung, kann aber List<? extends InterfaceA & InterfaceB>
nicht kompiliert werden. Betrachten Sie das folgende vollständige Snippet:
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>();
}
}
Es scheint, dass die Semantik von bar
genau definiert sein sollte - ich kann mir keinen Verlust an Typensicherheit vorstellen, indem ich eine Schnittmenge von zwei Typen anstelle von nur einem zulasse. Ich bin mir sicher, dass es eine Erklärung gibt. Weiß jemand was es ist?