Blog

Welche Generika schlucken

Jeroen van Erp

Jeroen van Erp

Aktualisiert Oktober 22, 2025
3 Minuten

Die Szene beginnt... Eine idyllische Landschaft entfaltet sich vor unseren Augen, in der Ferne sehen wir eine Gestalt auf uns zukommen. Er trägt den Namen Artus, König der Briten...

[code lang="java"] public class Arthur { // Einige Interna von Arthur, auf die wir später zurückkommen werden. } [/code] brücke_des_todesAls wir uns umdrehen, sehen wir eine Schlucht. Über der Schlucht liegt eine alte Seilbrücke mit Holzstufen und auf dieser Seite der Brücke sehen wir den Brückenwärter. [code lang="java"] public class BridgeKeeper { // Einige Interna des BridgeKeepers, auf die wir später zurückkommen werden. } [/code] Wenn Arthur sich dem BridgeKeeper nähert, spricht der BridgeKeeper: "Halt! Wer die Brücke des Todes überqueren will, muss mir diese drei Fragen beantworten, bevor er die andere Seite sieht.". [code lang="java"] public class Question { öffentlich <S> S Antwort(Antwort<S> a) { return a.doAnswer(); } public interface Antwort<S> { S doAnswer(); } } [/code] südafrikanische SchwalbeeuropeanswallowNachdem Arthur die ersten beiden Fragen richtig beantwortet hat, stellt ihm der Brückenwärter die dritte und letzte Frage: "Wie hoch ist die Fluggeschwindigkeit einer unbeladenen Schwalbe". Nun ist unser Arthur nicht ohne Grund zum König ernannt worden und kennt die Unterschiede zwischen Schwalben: [code lang="java"] public class Swallow {} public class EuropeanSwallow extends Swallow {} public class AfricanSwallow extends Swallow {} [/code] Also fragt Arthur den Brückenwärter: "Was meinst du, eine afrikanische oder eine europäische?" [code lang="java"] public class Arthur { public void query(BridgeKeeper keeper) { Question whichSwallow = new Question(); Swallow s = keeper.answer(whichSwallow); [/code] } } Worauf der BridgeKeeper antwortet mit: "Uhmm.... Ich weiß es nicht", woraufhin er in die Schlucht geworfen wird... [code lang="java"] public class BridgeKeeper { öffentlich <S erweitert Schwalbe> S Antwort(Frage Frage) { return Frage.Antwort(new Frage.Antwort<S>() { public S doAnswer() { return determineSwallow(); } }); } privat <S erweitert Schwalbe> S determineSwallow() { null zurückgeben; } } [/code] Obwohl dieser Code eigentlich sauber aussieht, lässt er sich mit Ihrem Java-Compiler nicht kompilieren. Obwohl sowohl IntelliJ als auch Eclipse keine Fehler anzeigen, führt die Kompilierung mit dem echten JDK zu folgender Fehlermeldung type parameters of <S>S cannot be determined; no unique maximal instance exists for type variable S with upper bounds S,Swallow Hier liegt tatsächlich etwas Grundlegendes vor. Der Compiler kann nicht auf den richtigen generischen Typ für den Rückgabewert von determineSwallow() schließen. Der Grund dafür ist, dass die Rückgabetypen von determineSwallow und answer unabhängig voneinander sind. Hierfür gibt es einen seit langem bestehenden Fehler im JDK, der nun endlich in Java7 behoben wird. Die Lösung ist denkbar einfach: Entweder Sie führen einen expliziten Cast durch oder Sie rufen die Methode mit dem vorhandenen generischen Rückgabetyp auf, wie unten gezeigt, und ignorieren einfach die Warnung Ihrer IDE, dass der generische Typ abgeleitet werden kann... [code lang="java"]public class BridgeKeeper { öffentlich <S erweitert Schwalbe> S Antwort(Frage Frage) { return Frage.Antwort(new Frage.Antwort<S>() { public S doAnswer() { return BridgeKeeper.this.<S>determineSwallow(); } }); } privat <S erweitert Schwalbe> S determineSwallow() { null zurückgeben; } } [/code]

Verfasst von

Jeroen van Erp

Contact

Let’s discuss how we can support your journey.