Verwirrt beim Java Collection Framework aufruf!

Bitte aktiviere JavaScript!
Guten Tag,

ich habe nachgelesen, dass
ArrayLists, LinkedLists, etc. mit unterschiedlichen Elementtypen inkompatible sind und nicht gemischt werden können!

somit liefert folgender Aufruf einen Compiler Fehler:
Java:
ArrayList<Object>     objectlist = new ArrayList<String>(); //FEHLER
Bis jetzt habe ich mich mit den Generics noch nicht beschäftigt vielleicht fällt dann erst der Groschen.
Denn wieso funktioniert dann dieser Aufruf?
Java:
List<Object> ol = new LinkedList<>();
Diese erstelle LinkedList kommt einem Object[] gleich. Dort kann ich sämtliche Object rein stecken und über "hoffentlich" vorhandene toString() Mehtode mit foreach Schleife ausgeben lassen:
Java:
for(Object i:l)
            System.out.println(i.toString()+" ");
Ich verstehe einfach nicht was diese <> Klammer tun?
In Java ist eine Insel steht weiterhin dieses: (was ja schon die Antwort ist denke ich :D)
Da in allen Datenstrukturen jedes Exemplar einer von Object abgeleiteten Klasse Platz findet, sind die Listen grundsätzlich nicht auf bestimmte Datentypen fixiert, doch Generics spezifizieren diese Typen genauer.

Da ich oben diese spezifikatioin auf Object lege ist der Generice Typ Objet und somit alles zugelassen?
Vielleicht könnt Ihr mir das genauer erklären :) wäre euch sehr dankbar :)

LG
 
A

Anzeige


Vielleicht hilft dir dieser Kurs hier weiter: (hier klicken)
Nein. Der Diamond "<>" dient nur dazu, weniger Schreibarbeit im Wiederholen desselben Typargumentes bei der Instanziierung eines generischen Typs und bei der Deklaration der zugewiesenen Variablen zu haben.
Also z.B.:
Java:
List<String> list = new ArrayList<>();
// ist dasselbe wie:
List<String> list = new ArrayList<String>();
Siehe: https://docs.oracle.com/javase/tutorial/java/generics/types.html#diamond

Dein Code:
Java:
ArrayList<Object> objectlist = new ArrayList<String>();
liefert deswegen einen Fehler, weil generische Typen nicht covariant in den Typargumenten sind. Arrays sind allerdings covariant in dem Elementtyp, deshalb ist bei Arrays auch sowas möglich:
Java:
Object[] arr = new String[5];
Das geht nur nicht bei generischen Typen mit Typparametern.
 
Also das mit den <> sind die Generics.

Und wenn Du Zuweisungen machst, dann muss der Typ stimmen!

Also wenn Du eine Variable vom Typ X hast, dann kannst Du da nur X (oder davon abgeleitete Klassen) zuweisen. Ist ja klar: Wen Du eine Katze haben willst, dann kann man die nur eine Katze geben (Aber da kann es eine beliebige Katze sein.) Aber wenn man versucht, die einen Hund zu geben, dann wirst Du den nicht annehmen wollen.

Und das gilt auch bei Listen:
Wenn Du einen Behälter für beliebige Gegenstände (Object) haben willst: Da wirst Du einen Behälter nur für Bücher (In Deinem Code String) nicht annehmen.
Aber umgekehrt würde es gehen: Du willst einen Behälter für Bücher, aber nun bekommst Du einen Behälter in den du alles (Also auch Bücher) stecken kannst: Das wäre ok für Dich, oder?

Und die Generics dienen dazu, dass die Typsicherheit gegeben ist. Früher hat man dann Listen und so gehabt, die halt Object gespeichert haben. Aber wenn Du dann in die Liste, in der Autos gespeichert werden sollten, was anderes gespeichert hast, dann war das der Liste egal. Der Compiler hat nicht gemeckert. Aber wenn dann das Element ausgelesen wurde und als Auto verwenden werden sollte, dann gab es natürlich Probleme... Wurde dann oft durch Schreibarbeit gelöst: Was jetzt ein List<Auto> ist, war damals dann eine Klasse AutoList welches ein List hatte und alle Funktionen der List nur eben mit Auto als Typ, die dann von/zu Object gecastet wurden. (Zu Object muss man nicht casten, aber die Object der List wurden dann zu Auto gecastet.)
==> Also Generics haben hier uns viel Arbeit abgenommen....
 
somit liefert folgender Aufruf einen Compiler Fehler:
Java:
ArrayList<Object>     objectlist = new ArrayList<String>(); //FEHLER
Das kann man sich ganz einfach herleiten. Um es ganz deutlich herauszustellen, kann man das mal mit zwei Variablen schreiben:
Java:
ArrayList<String>     stringlist = new ArrayList<String>(); 
ArrayList<Object>     objectlist = stringlist;
objectlist.add(new int[]{1,2,3}); // fügt ein Array in die objectlist ein.
String str = stringlist.get(0); // örks
Daher ist die Zuweisung objectlist = stringlist nicht möglich.
 
Ja und mir ist auch die Tage aufgefallen das wenn man nur ArrayList objectlist = new ArrayList<>(); schreibt die Liste auch vom Typ Objekt ist.

Java:
        ArrayList slist = new ArrayList<>();
        Object a = 2;
        Object b = 3.14;
        Object c = "test";
        
        slist.add(a);
        slist.add(b);
        slist.add(c);
        
        slist.set(0, "23");
        
        System.out.println(slist.remove(2));
        System.out.println(slist.remove("3"));
        
        String ss = (String) slist.get(0);
Die Generics werde ich mir jetzt mal anschauen :) Denke dann wird das alles auch wieder etwas klarer :)

Danke nochmals für die schnellen und netten Antworten :)

LG
 
Ja und mir ist auch die Tage aufgefallen das wenn man nur ArrayList objectlist = new ArrayList<>(); schreibt die Liste auch vom Typ Objekt ist.
Klar. Auf der linken Seite gibst Du keinen Typ an, also wird Object angenommen (schon aus Gründen der Kompatibilität) und der Compiler spuckt eine Warnung aus, sobald Du eine normalerweise typsichere Methode verwendest.
 
Eine "Idioten" Frage hätte ich noch.
Wie bekomme ich Eclipse verklickert das die Klasse nun public class Rational<T> heißen soll?
Er macht immer daraus public class Rational.
Kennt Ihr das Problem?

LG
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben