Generics: Wildcards / Einschränkungen



  • Wo besteht hier der Unterschied?

    1.) E - Einschraenkung

    static public <E extends CharSequence> Collection<E> getLongWords(Collection<E> coll)
    [/quote]
    
    2.) ? - Alles zulässig
    [quote]
    static public <? extends CharSequence> Collection<E> getLongWords(Collection<E> coll)
    

    Das extends bei 1.) macht mich etwas stutzig. Warum Einschränkung wenn doch abgeleitet von CharSequence. Heißt das nur was von Charsequence abgeleitet ist?

    Bei 2.) somit CharSequence inbegriffen?



  • Wo besteht hier der Unterschied?

    1.) E - Einschraenkung

    static public <E extends CharSequence> Collection<E> getLongWords(Collection<E> coll)
    

    2.) ? - Alles zulässig

    static public <? extends CharSequence> Collection<E> getLongWords(Collection<E> coll)
    

    Das extends bei 1.) macht mich etwas stutzig. Warum Einschränkung wenn doch abgeleitet von CharSequence. Heißt das nur was von Charsequence abgeleitet ist?

    Bei 2.) somit CharSequence inbegriffen?



  • das zweite beispiel dürfte sich gar nicht kompilieren lassen, weil kein E existiert, es sei denn du hast E in der klassendeklaration spezifiziert, dann macht das beispiel auch keinen sinn.



  • Wo besteht denn nun genau der Sinn von dem E, diesem Platzhalter hierbei?

    Also E extends Charsequence. Ich verstehe die Bedeutung nicht.

    Danke!



  • Naja, damit gibst du dem Typen eben einen Namen und kannst an anderer Stelle diesen wieder verwenden. Vergleich zum Beispiel folgende Codesnippets:

    // 1. mit Typbezeichnung
    public <E extends CharSequence> Collection<E> foo(Collection<E> c) 
    
    // 2. ohne Typbezeichnung (kompiliert allerdings nicht .. dazu später)
    public Collection<? extends CharSequence> foo(Collection<? extends CharSequence> c)
    

    Von den Einschränkungen der Typen sind die beiden Versionen prinzipiell identisch, da der Typ in jedem Fall die Schnittstelle CharSequence implementieren muss. Allerdings geht in der zweiten Version nicht hervor, dass der Returntyp gleich dem ersten Parameter sein muss. Es besteht ja keinerlei Verbindung zwischen diesen beiden Typen. Theoretisch könnte der Returntyp also Collection<String> sein, während der Parameter vom Typ Collection<StringBuilder> ist. Nachdem der Caller in diesem Fall keinen Einfluss auf den Returntyp hat, ist es natürlich Schwachsinn hier einen Wildcard-Parameter zu verwenden, was auch der Grund dafür ist, dass die zweite Variante nicht kompilieren wird.

    // 2. ohne Typbezeichnung (kompiliert diesmal)
    public Collection<CharSequence> foo(Collection<? extends CharSequence> c)
    

    HTH! 🕶



  • Noch einmal eine Frage:
    Wieso kann man nach public einen Typ angeben und nach Collection und nach getLongWords die wie verwendet werden?

    Heißt das <E extends Charsequence> beschreibt E ?

    Ich verstehe die Syntax nicht ganz.

    static public <E extends CharSequence> Collection<E> getLongWords(Collection<E> coll)

    Danke!!



  • Du scheibst eine generische Methode, mit E als Platzhalter für einen Typ.
    Im Methodenkopf musst du angeben welche Eigenschaften E haben soll, das sieht halt so aus:

    <E extends CharSequence>

    Prototyp für ne generische Funktion:

    [Zugriffsmodifizier] [andere Modifizierer] [<Generic Info>] [Return-Wert] name( [Parameter] )

    In deinem Fall muss der Typ, der dann für E eingesetzt wird, von CharSequence erben.


Anmelden zum Antworten