Generics

Status
Nicht offen für weitere Antworten.

mouk

Aktives Mitglied
Hi!

Ich finde es etwas komisch wie Generics funktionieren. Wieso ist es notwendig, wenn man eine neue Instanz von zB ArrayList erzeugt, auch bei "new ArrayList<String>()" den Typenparameter anzugeben, würde es nicht ausreichen wenn man das nur bei der Referenz macht?

Bei allen anderen Operationen wird doch auch der Typ der Referenz verwendet, zB:

Code:
import java.util.ArrayList;

public class Test {
	
	public static void main(String[] args) {
		
		ArrayList<String> list = new ArrayList<String>();
		list.add("Hallo");
		
		ArrayList list2 = list;
		list2.add(34.324);
		
		ArrayList<Integer> list3 = list2;
		list3.add(643);
	}
}

Bei diesem Code lässt mich der Compiler doch letztendlich wieder jedes Objekt einer beliebigen Klasse der ArrayList hinzufügen, obwohl ich sie bei der Erstellung mit <String> parameterisiert habe.
Also was hat das dann für einen Sinn gehabt?

fg, mouk
 
S

SlaterB

Gast
Was meinst du denn mit 'notwendig'?
Bei mir funktioniert
ArrayList<String> list = new ArrayList();
auch ohne Typparameter.

Der Compiler meckert nur dass das dann nicht mehr typsicher ist.
Denn der Compiler weiß nicht, dass new ArrayList(); eine leere Liste ist und damit genau das gleiche wie new ArrayList<String>();

Das zu erkennen fordert halt ein bisschen Nachdenken was im Moment fehlt.

-------
Wenn du das einmal haben willst, dann demnächst vielleicht auch

ArrayList l = new ArrayList();
ArrayList<String> l2 = l;

ohne Fehlermeldung?

Und später gar

ArrayList l = new ArrayList();
// beliebiger Code
ArrayList<String> l2 = l;
?

------------
Das wäre Schritt für Schritt immer schwieriger,
der Compiler macht es sich aber ganz einfach:

ArrayList l = new ArrayList();
l.add(3);
l.add(new Object());
ArrayList<String> l2 = l;

muss auf jeden Fall zu einem Fehler (bzw. Warnung) führen.
Wie kann man das am einfachsten erkennen?
Man schaut einfach, ob das Objekt l bei der Zuweisung zu l2 vom Typ ArrayList<String>() ist.

Das ist zwar strohdumm in Vergleich zu dem was vielleicht toll wäre, klappt dafür fehlerlos.

Hat dabei zur Folge, dass
ArrayList<String> list = new ArrayList();
zu genau dem gleichen Fehler/ Warnung führt.
 

mouk

Aktives Mitglied
Danke für deine Antwort. Leider konnte ich deinen Erklärungen nicht ganz folgen. Es ist ja nicht so das ich das so machen möchte wie in dem Beispiel. Ich habe eben nur etwas rumprobiert.

Ich verstehe weiterhin nicht was unsicher sein soll wenn ich ArrayList<String> list = new ArrayList(); schreibe.

Ich bekomm auch ohne die Angabe von "new ArrayList<String>()" sämtliche Warnungen, Fehler und Checks die ich sonst auch bekommen würde.

fg, mouk
 

byte

Top Contributor
mouk hat gesagt.:
Ich verstehe weiterhin nicht was unsicher sein soll wenn ich ArrayList<String> list = new ArrayList(); schreibe.

Ich bekomm auch ohne die Angabe von "new ArrayList<String>()" sämtliche Warnungen, Fehler und Checks die ich sonst auch bekommen würde.

Und ich verstehe nicht, was es da nicht zu verstehen gibt. Alleine die Tatsache, dass es überhaupt Warnungen gibt, sagt doch schon, dass es nicht sicher sein kann. Der Teil links vom = ist quasi die Referenz und der Teil rechts das eigentliche Objekt, das erzeugt wird. Beides muss generisch definiert werden, um Typsicherheit zu gewährleisten.

ArrayList<String> list = new ArrayList(); ist genaus unsicher, wie das hier:

Code:
ArrayList<String> list;
		
ArrayList list2 = new ArrayList();
		
list2.add("hallo");
list2.add(17);
list2.add(new Object());
		
list = list2;
 

mouk

Aktives Mitglied
Was in deinem Beispiel unsicher ist verstehe ich.
Ich habe mal kommentiert so wie ich mir das vorstelle.

Code:
ArrayList<String> list;
      
ArrayList list2 = new ArrayList();
      
list2.add("hallo");
list2.add(17);
list2.add(new Object());
      

list = list2; // Der Compiler erkennt hier das die Referenz list das Attribut <String> hat und das die Referenz list2 nicht
                // parameterisiert ist und gibt deshalb eine Warnung aus. Also benötigt er doch die Angabe von 
                // "new ArrayList<String>()" gar nicht um zu erkennen ob das nun Typensicher ist oder nicht
 

byte

Top Contributor
Also benötigt er doch die Angabe von "new ArrayList<String>()" gar nicht um zu erkennen ob das nun Typensicher ist oder nicht

Ähm doch, genau deswegen benötigt er eben diese Information. :roll:

Eine Liste ist nur dann typsicher, wenn sichergestellt ist, dass nur Objekte eines bestimmten Typs rein können. Wie man Beispiel oben zeigt, kannst Du das nur sicherstellen, wenn auf beiden Seiten vom = diese Typsicherheit generisch festgelegt wird.

new ArrayList<String>() <--- kann ausschließlich Strings beinhalten => typsicher
new ArrayList() <--- kann beliebige Objekte beinhalten => typunsicher
 

mouk

Aktives Mitglied
new ArrayList<String>() <--- kann ausschließlich Strings beinhalten => typsicher

Aber genauso ist es doch eben nicht. Schau dir folgenden Code an:

Code:
ArrayList<String> list = new ArrayList<String>();

list.add("Hallo");
      
ArrayList list2 = list;

list2.add(34.324); // Die mit "new ArrayList<String>()" erzeugte Instanz von ArrayList akzeptiert neuerdings auch 
                          // doubles, nur weil sie mit einer nicht parameterisierten Referenz verbunden wurde.
 
S

SlaterB

Gast
list2 ist als ArrayList definiert, da ist es egal was für ein Objekt drin ist,

list2.add(34.324);
gibt keinen Fehler da kein String-Typ benötigt wird


" kann ausschließlich Strings beinhalten => typsicher"
heißt
"der Compiler kann sicherstellen, dass dieses Objekt (SOLANGE ES ALS ArrayList<String> BEHANDELT WIRD) nur Strings enthält,
wenn ein anderes Objekt in dieser Liste wäre, hätte es bereits vorher, beim Hinzufügen dieses Objektes in diese Liste, eine Warnmeldung gegeben",

das ganze gilt nur lokal für eine bestimmten Codebereich,
das ist nur eine Hilfe für den Compiler in diesem Codebereich Warnmeldungen auszugeben (als Hilfe beim Programmieren),
verboten wird dabei nix

-----------
Typsicherheit ist eine Kette von Anforderungen und Erfüllungen,

ArrayList<String> list = new ArrayList<String>(); // ist muss A<String> sein, ist das Objet recht A<String>? jo, kein Fehler
list.add("Hallo"); // nur Strings dürfen rein (list ist ja vom Typ A<String>), ist Objekt ein String?, jo, kein Fehler

ArrayList list2 = list; // list2 muss irgendeine A sein, ist list2 eine A? jo, kein Fehler,
list2.add(34.324); // list2 ist eine GANZ NORMALE A, welches A-Objekt in dieser A-Variable drin ist IST UNBEKANNT (vielleicht gar null -> NullPointerException), in eine A dürfen beliebge Objekte, ist Objekt ein Objekt? selbstverständlich, jedes Objekt darf da rein, kein Fehler
 

mouk

Aktives Mitglied
Aber wenn man mit einer ArrayList<String> Referenz auf eine ArrayList zugreift, kann man sowieso nur Strings hinzufügen, egal ob man die Instanz mit "new ArrayList<String>()" erzeugt hat oder nicht.

Folgende 2 Codeblöcke sind von der Funktionsweise her völlig identisch:
Code:
      ArrayList<String> list = new ArrayList<String>();
		list.add("Hallo");
		
		ArrayList list2 = list;
		list2.add(334.45);
		
		

		
		ArrayList<String> list3 = new ArrayList();
		list3.add("Hallo");
		
		ArrayList list4 = list3;
		list4.add(334.45);

Kann mir vielleicht jemand ein konkretes Codebeispiel geben für einen Fehler der passieren könnte wenn ich "new ArrayList()" verwende, der nicht passiert wäre wenn ich "new ArrayList<String>()" verwendet hätte? Ich habe nämlich schon die ganze Zeit rumprobiert, ich bin aber auf keinen grünen Zweig gekommen. ;-)
 
S

SlaterB

Gast
richtig, die Warnmeldung sagt ja auch NICHT, dass du danach die Liste nicht wie eine korrekt definierte ArrayList<String> verwenden kannst,

das klappt nämlich wunderbar,
und wenn du dir sicher sein kannst, das die erste Zuweisung auch korrekt ist, obwohl der Compiler meckert, dann ist alles wunderbar,

so kann man durchaus Generics sinnvoll einsetzen, nach dieser ersten Warnung funktioniert weiterhin alles recht sinnvoll

----------

das einzige was die Warnmeldung dir sage will, ist, dass AN GENAU dieser Stellen eine Gefahr besteht, nämlich dass hier falsche Objekte in die ArrayList kommen,

schlicht und einfach genau die richtige Warnmeldung für eine solche Situation ;)
 
S

SlaterB

Gast
der Fehler ist

ArrayList list = new ArrayList();
list.add(2);

ArrayList<String> list2 = list;
String st = list2.get(0); // ClassCastException


über eine solche Exception darf man sich nicht wundern, schließlich hat einen der Compiler extra gewarnt ;)

-----------

wie gesagt kann bei
ArrayList<String> list3 = new ArrayList();
unmöglich ein Fehler auftreten,
aber der Compiler ist zu dumm, um zu erkennen, dass die augenscheinlich typunsichere ArrayList() leer sein muss und damit unmöglich ein Problem darstellen kann,

schlicht nicht sichtbar für den Compiler,
für den ist dieser Einzeiler genauso gefährlich wie


ArrayList list = new ArrayList();
list.add(2);

ArrayList<String> list2 = list;
 

mouk

Aktives Mitglied
SlaterB hat gesagt.:
das einzige was die Warnmeldung dir sage will, ist, dass AN GENAU dieser Stellen eine Gefahr besteht, nämlich dass hier falsche Objekte in die ArrayList kommen,

Aber wie kann an dieser Stelle eine Gefahr bestehen das falsche Objekte in die ArrayList kommen, wo sie doch noch nichtmal existiert sondern erst mit new erzeugt wird?
 
S

SlaterB

Gast
siehe meine zweite Antwort eben, der Compiler ist eben doof,
so denke ich mir das jedenfalls, sonst sähe ich auch keinen Grund genau wie du ;)

--------

übrigends müsste der Compiler auch prüfen, ob nicht etwa im Konstruktor der ArrayList heimlich schon ein paar Objekte eingefügt werden und ähnliche Späße,
das ganze könnte also nur über eine Positivliste wie 'java.util.ArrayList keine Gefahr' gemacht werden, oder auch 'java.util keine Gefahr',
aber kann man sich bei sowas sicher sein?, will man das für alle Java-Klassen/-Pakete machen?

Generics sollte wohl doch eher selber generisch sein, also keine Unterscheidung zwischen ArrayLists oder selbstdefinierten Klassen machen,
da ist eine solche Überprüfung dann eh nicht mehr möglich
 

mouk

Aktives Mitglied
SlaterB hat gesagt.:
siehe meine zweite Antwort eben, der Compiler ist eben doof,
so denke ich mir das jedenfalls, sonst sähe ich auch keinen Grund genau wie du ;)

Ich glaub so langsam kapier ich es. :D
Nur so nebenbei, was meint der Compiler eigentlich mit "unchecked conversion"? Ja ich kann Englisch, ich versteh aber trotzdem nicht was er da genau meint.. :wink:

Ich hab jetzt auch noch ein Beispiel gefunden, wo es Sinn macht <String> zu schreiben:

Code:
public class Test {
	
	public static void main(String[] args) {
		
		NewList<String> list = new NewList<String>(2343);
	}
}

class NewList<T> extends ArrayList<T> {	
	NewList(T t) {
		add(t);
	}
}

Wenn man "new NewList(2343)" schreibt schluckt es der compiler, bei "new NewList<String>(2342) bekommt man allerdings eine schöne Fehlermeldung.

fg, mouk
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Best Practice Generics mit Enum Allgemeine Java-Themen 3
H Kombination Interface und Abstrakte Klasse bei Generics Allgemeine Java-Themen 3
Zeppi Cast Object in Generics Allgemeine Java-Themen 4
P Generics und Arrays Allgemeine Java-Themen 6
M Generics / Typen Allgemeine Java-Themen 1
Kirby.exe InsertionSort mit Generics Allgemeine Java-Themen 33
Kirby.exe Vererbung bei Generics Allgemeine Java-Themen 7
H Klarnamen etc... (von Wie Generics lernen?) Allgemeine Java-Themen 26
D Wie Generics lernen? Allgemeine Java-Themen 26
L Compiler-Fehler Generics beim Anhängen von Predicates Allgemeine Java-Themen 1
W Vererbung Generics - mal wieder die verhaßte Rückwärtskompatibilität Allgemeine Java-Themen 2
S Verstaendnisfrage Generics Allgemeine Java-Themen 19
W Generics + Vererbung Allgemeine Java-Themen 47
I Methoden Generics-Methode Allgemeine Java-Themen 3
D Mit Generics arbeiten - Übungsaufgabe Allgemeine Java-Themen 3
K Factory Pattern: Mit Generics umgehen Allgemeine Java-Themen 6
G Generics Allgemeine Java-Themen 31
perlenfischer1984 Liste mit generics zurück liefern Allgemeine Java-Themen 8
Hacer Generics & Collections Allgemeine Java-Themen 8
Neumi5694 Interface Generics für Enum-Filterung verwenden Allgemeine Java-Themen 5
H Collector Generics Problem (incl. Stream & Lambda) Allgemeine Java-Themen 4
C Gemeinsame Oberklasse zweier Generics Allgemeine Java-Themen 10
erdmann Datentypen Methodendeklaration mit Generics Allgemeine Java-Themen 2
Z Datentypen Verschachtelte Generics Allgemeine Java-Themen 1
Neumi5694 Datentypen Generics Allgemeine Java-Themen 5
S Mit Generics Klasse erstellen die selbst T erweitert..? Allgemeine Java-Themen 4
Tarrew Generics - Type erasure Allgemeine Java-Themen 5
N Problem mit Generics und Interface Allgemeine Java-Themen 4
H Generics als Parameter Allgemeine Java-Themen 1
kaoZ Generics und Vererbung Allgemeine Java-Themen 3
A Datentypen Generics: Wie am besten auf Typparameter zugreifen Allgemeine Java-Themen 2
C Generics Objekt in ArrayList Allgemeine Java-Themen 2
vandread Kleine Generics Aufgabe aus einer Prüfung... wie ist das gemeint? Allgemeine Java-Themen 6
G Generics sind zu streng - oder ich zu naiv? Allgemeine Java-Themen 3
G Verschachtelte Generics Allgemeine Java-Themen 2
O Generics Allgemeine Java-Themen 42
M Problem mit Generics Allgemeine Java-Themen 10
M Generics (bounded wildcards statt Interface Bezeichnern) -- Sinn oder Unsinn? Allgemeine Java-Themen 2
darekkay Generics: Wildcard und Object Allgemeine Java-Themen 5
H Collections Generics und Reflection Allgemeine Java-Themen 6
F Google Guice + Generics + Vererbung Allgemeine Java-Themen 5
H Problem mit Java Generics Allgemeine Java-Themen 6
J Generics: Typparameter als Klasse zurückliefern Allgemeine Java-Themen 4
H Generics Allgemeine Java-Themen 5
P Probleme mit Generics Allgemeine Java-Themen 5
B Generics und primitve arrays Allgemeine Java-Themen 6
M Generics Allgemeine Java-Themen 11
1 Collections Generics, internes Verhalten Allgemeine Java-Themen 16
T Warnungsfreie Verwendung von Generics Allgemeine Java-Themen 11
M Probleme mit Generics Allgemeine Java-Themen 5
D Java Generics Allgemeine Java-Themen 8
2 Generics: bounded wildcards Allgemeine Java-Themen 4
J Generics / vermeiden von downcasts Allgemeine Java-Themen 2
2 Generics oder nicht? Allgemeine Java-Themen 8
E Problem mit Generics und Comparable Allgemeine Java-Themen 16
W Erweitern einer Klasse mit Generics Allgemeine Java-Themen 8
H Generics für Methode Allgemeine Java-Themen 14
N Überladen mit Hilfe von Generics Allgemeine Java-Themen 3
S Generics: Fuer Set<T> ein T-Klassenobjekt erhalten? Allgemeine Java-Themen 3
Q Der innere Typ von Generics? Allgemeine Java-Themen 3
N Generics-NullpointerException Allgemeine Java-Themen 7
2 Generics - Typ Allgemeine Java-Themen 12
P Generics Problem Allgemeine Java-Themen 10
S Type safety Warnings beim casten von Generics Allgemeine Java-Themen 6
N Generics Allgemeine Java-Themen 3
V Frage zu Generics Allgemeine Java-Themen 2
S java generics klassen deklaration Allgemeine Java-Themen 7
B hashtable für unterschiedliche Typen - mit Generics Allgemeine Java-Themen 8
E Generics Allgemeine Java-Themen 3
MQue Generics Allgemeine Java-Themen 4
R Problem mit Reflection und Generics Allgemeine Java-Themen 3
C Klassen, die aufeinander verweisen (mit Generics) Allgemeine Java-Themen 16
G Generics - W.card unter Nutzung von Annotationsklasse? Allgemeine Java-Themen 6
G sortieren von generics Allgemeine Java-Themen 10
G Generics in Map. Type of value abhängig vom key Allgemeine Java-Themen 3
A Generics Verständnisfrage Allgemeine Java-Themen 7
Z Generics funzt nicht? Allgemeine Java-Themen 2
T Generics Allgemeine Java-Themen 18
G ComboBox: Nur eine Art Klasse zulassen (Generics) Allgemeine Java-Themen 3
J Generics Expertenwissen? Allgemeine Java-Themen 5
S Generics-Problem Allgemeine Java-Themen 3
T Generics und Wil-dcards Allgemeine Java-Themen 8
Q Typen von Generics & Casten Allgemeine Java-Themen 3
S Generics Allgemeine Java-Themen 2
R Problem mit Generics Allgemeine Java-Themen 2
G Trotz Generics Cast-Fehler! Allgemeine Java-Themen 5
T TreeMap durch Comparator mit Generics sortieren Allgemeine Java-Themen 9
T Generics und instanceof Allgemeine Java-Themen 10
T Generics und Exceptions Allgemeine Java-Themen 6
M Beliebig viele Typen bei Generics Allgemeine Java-Themen 3
G Reflection objekt mit generics erzeugen Allgemeine Java-Themen 5
S Singleton Pattern mit Generics Allgemeine Java-Themen 4
G Generics und Comparable Allgemeine Java-Themen 11
H Generics Problem Allgemeine Java-Themen 3
F Generics: spricht etwas dagegen raw types zu verwenden? Allgemeine Java-Themen 31
M Generics - besser programmieren, Warnung umgehen Allgemeine Java-Themen 4
E Java, UML, Generics Allgemeine Java-Themen 6
P Array von Vectoren + Generics Allgemeine Java-Themen 6
M ArrayList erweitern - generics Allgemeine Java-Themen 4
E Generics -> UML Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben