[Java] Mal ne Frage...

  • [Java] Mal ne Frage...

    Anzeige
    Mir kam vor einiger Zeit die Frage auf, ob es einen Unterschied zu den folgenden Programmabschnitten gibt?
    Folgendes sei vorhanden:

    Java-Quellcode

    1. import java.util.List;
    2. public class BaseClass {
    3. public void runThisMethod(List<BaseClass> base) {
    4. /* ... */
    5. }
    6. public void runThatMethod(List<? extends BaseClass> base) {
    7. /* ... */
    8. }
    9. /** weiteres diverses Zeug... */
    10. }
    Alles anzeigen

    Java-Quellcode

    1. public class SubClass extends BaseClass {
    2. /** von BaseClass geerbt... */
    3. }
    Diese Abschnitte zeigen, dass eine BaseClass mit diversen Content erstellt und eine SubClass ebenfalls erstellt worden ist, welche alles öffentliche von BaseClass erbt.

    Nun wird hier folgendes gezeigt:

    Java-Quellcode

    1. import java.util.List;
    2. import java.util.ArrayList;
    3. public class Runner {
    4. public static void main(String... s) {
    5. SubClass sub1 = new SubClass();
    6. SubClass sub2 = new SubClass();
    7. List<BaseClass> list1 = new ArrayList<>();
    8. List<BaseClass> list2 = new ArrayList<>();
    9. list1.add(sub1);
    10. list2.add(sub2);
    11. // List<BaseClass>
    12. sub1.runThisMethod(list1);
    13. // List<? extends BaseClass>
    14. sub2.runThatMethod(list2);
    15. /* ... */
    16. }
    17. }
    Alles anzeigen
    Nun zu meiner Frage: Welches der beiden oben gezeigten Programmsnippets beherbergt mehr Sicherheit und Konformheit? So wie ich das aus dem Stehgreif heraus ermitteln kann, müssten sowohl beide Abschnitte funktionieren als auch keinen entscheideren Unterschied beherbergen, oder?
    Re|kur|sion, die <lat.>
    siehe Rekursion
  • Parano.Oya schrieb:

    Nun zu meiner Frage: Welches der beiden oben gezeigten Programmsnippets beherbergt mehr Sicherheit und Konformheit? So wie ich das aus dem Stehgreif heraus ermitteln kann, müssten sowohl beide Abschnitte funktionieren als auch keinen entscheideren Unterschied beherbergen, oder?
    Die Generics fliegen dank Type Erasure beim Kompilieren raus, deshalb werden dir die Methoden den identischen Byte-Code fabrizieren und funktionell identisch sein, sofern sie kompiliert werden. Aber es kann sein, dass dir Methode A kompiliert werden würde und Methode B nicht, oder umgekehrt - je nachdem, wie du sie benutzt.

    Angenommen, du gibst List<? extends BaseClass> base als Parameter-Typ an. Du sagst, dass du eine Liste mit einem Typ erwartest, der sich irgendwie von BaseClass ableitet. Diese Bedingung erfüllt auch beispielsweise List<SubClass>. Das ist problematisch, wenn du beispielsweise in die Liste etwas einfügen willst. In einer List<SubClass> wären beispielsweise keine BaseClass-Objekte erlaubt.

    Er erkennt dir aber die falsche Nutzung vorher und bricht dir mit einem Compile-Fehler ab, wenn du Murks baust und dort nachbessern musst. Infos gibt's beispielsweise da torsten-horn.de/techdocs/java-…tendsNumber-versus-Number oder direkt auf der Oracle-Seite docs.oracle.com/javase/tutoria…a/generics/wildcards.html

    Ich benutze meist den Ansatz ohne Wildcard und mir fällt auch gerade nicht ein, wann und ob ich überhaupt schon mal die Wildcards benutzt habe.

    MfG
    Videoempfehlungen:
    ShimmyMC
    NuRap
    ShimmyMC
    Napoleon Bonaparte

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von RealLiVe ()