2Danke
ERLEDIGT
NEIN
NEIN
ANTWORTEN
9
9
ZUGRIFFE
1429
1429
EMPFEHLEN
-
Hallo!
Hoffentlich ist diese Frage genau hier "erlaubt".
Da es um Datenstrukturen geht, denke ich, ist es wohl korrekt.
Gegeben sind zwei Listen:
Code java:1 2 3 4 5 6 7 8
List<Number> list14 = null; List<? super Integer> list15 = null; //list14 = list15; // Compilerfehler incompatible types //Zeile 3 list15 = list14; // Zeile 4, OK // <? super Integer> bedeutet: <Integer> und alle Super-Klassen von <Integer>
Kann mir jemand erklären, warum die Zuweisung in Zeile 4 in Ordnung ist?
Im konkreten Fall könnte da eine Typ-Zuweisung "<Integer> = <Number>" sein,
was, denke ich, nicht passt.
Kann man es so deuten, dass der Compiler großzügig bzw. wohlwollend entscheidet,
weil bei Zuweisung "<? super Integer> = <Number>" könnte auch
Typ-Zuweisung "<Number> = <Number>" sein oder auch
Typ-Zuweisung "<Object> = <Number>"
sein, was ja passt.
Viele Grüße
Steve222
-
19.02.11 15:52 #2
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.885
- Blog-Einträge
- 29
Hallo,
schau mal hier:
http://www.angelikalanger.com/Generi...ts.html#FAQ101
http://www.tutorials.de/java/367497-...-generics.html
Schau mal hier:
Die Deklaration von List<? super Integer> superOfIntegers; besagt, dass superOfIntegers zwar Werte vom Typ Integer oder seiner Basis-Klassen enthalten kann, jedoch hier das "Constraint" ? super Integer unterschiedliche Auswirkungen. Zum einen ist superOfIntegers.set(...) fest auf Integer getyped.... man kann also diese Liste nur um tatsächliche Integers erweitern bzw. mit Integern manipulieren...Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
package de.tutorials; import java.util.Arrays; import java.util.Iterator; import java.util.List; public class SuperGenericsExample { public static void main(String[] args) { List<Number> numbers = Arrays.<Number>asList(0.0); //Double List<? super Integer> superOfIntegers = numbers; Number number = numbers.get(0); //returns number Iterator<Number> numberIterator = numbers.iterator(); Object value = superOfIntegers.get(0); //returns Object NOT Integer ... superOfIntegers.set(0, /* accepts only integers*/ Integer.valueOf(1)); Iterator<? super Integer> superIntegerIterator = superOfIntegers.iterator(); superOfIntegers.add(/* accepts only integers*/ Integer.valueOf(0)); } }
Auslesen kann man jedoch nur den "lower bound" ... und der ist in unserem Fall durch das ? -> Object.
Deshalb gibt die get Methode nur Object zurück.
Dieser Mechanismus macht sich das PECS-Prinzip zu nutze siehe in den oberen Links für weitere Einzelheiten.
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
Hallo Tom,
Du schriebst u.a.:
und das irritiert mich.Auslesen kann man jedoch nur den "lower bound" ... und der ist in unserem Fall durch das ? -> Object.
? super SubType " (wildcard with lower bound), bedeutet
alle SuperTypen von SubType und SubType selbst.
Laut Fr.A.Langer ist <? super Integer> eine "wildcard with lower bound" und der lower bound
ist dann enstprechend "Integer". Oder?
Es kommt mir vor, als würdest Du unter "lower bound" den SuperTyp verstehen!?
Viele Grüße
Steve222
-
19.02.11 18:07 #4
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.885
- Blog-Einträge
- 29
Hallo,
okay, kann sein, dass ich da was durcheinander gebracht habe. Finde die Formulierungen ziemlich kompliziert... für mich war der lower Bound der Typ den ich mindestens bekomme beim auslesen...
Was ist denn genau der upper bzw. lower bound einer generischen Collection? Ist der lower bound der allgemeinste Typ mit dem ich mit der Collection arbeiten kann? Was bedeutet arbeiten in diesem Fall? Lesen? Schreiben? Beides? Weil ...
List<? super Integer> superOfIntegers -> schreiben kann ich nur Integer ... lesen kann ich jedoch Object (da ja alle möglichen SuperTypen von Integer)zurück kommen können...
Im Prinzip definiert man ja mit List<? super T> eine Einschränkung für die Verwendung der Liste.
Diese Einschränkung besagt, dass zur Liste nur Werte vom Typ T hinzgefügt (add(...) ) und nur Werte vom Typ T gesetzt (set(int,...) werden können. Ausgelesen werden können jedoch Werte vom beliebigen Super-Typen von T und da bleibt nur Object über...
Deshalb ist die Zuweisung im Falle von:
Code java:1 2
List<Number> numbers = Arrays.<Number>asList(0.0); //Double List<? super Integer> superOfIntegers = numbers;
auch erlaubt... denn ausgelesen werden kann aus superOfIntegers nur Werte vom Typ Object und dass sind Numbers oder Integer auf jeden Fall.
Aber wie heißts noch so schön: "Wer meint generics zu verstehen hat generics nicht verstanden...."
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
Hallo Tom,
gut, dass Du pragmatisch daran gehst und Lesen und Schreiben ausprobierst, aber dennoch sollten die Begrifflichkeiten geklärt werden.
Du fragtest
Diese Begriffe sind die, die Frau Langer verwendet und ich verstehe sie so:Was ist denn genau der upper bzw. lower bound einer generischen Collection? Ist der lower bound der allgemeinste Typ mit dem ich mit der Collection arbeiten kann?
1.) lower bound ( ca.: untere Begrenzung) und auch upper bound ( ca.: obere Begrenzung)
gibt es so erstmal NUR im Zusammenhang mit dem wildcard-Zeichen "?", wenn es um
Typisierungen von Collections, also dem Thema "generics" geht.
Wie Du mitteilst geht es darum jeweils Collection-Objekte auf auf einen bestimmten
Typ, oder auf einige wenige Typen festzulegen.
Ohne wildcard, also z.B. <String>, bedeutet, dass in dem so markierten Collectionobjekt nur
Strings hinzugefügt werden dürfen.
Mit wildcard, also z.B. <? extends String> bedeutet, dass in das so markierte Collectionobjekt nur
Strings UND Subclass-Objekte von String hinzugefügt werden dürfen. "String" ist dann "upper bound".
Mit wildcard, also z.B. <? super String> bedeutet, dass in das so markierte Collectionobjekt nur
Strings UND Superclass-Objekte von String hinzugefügt werden dürfen. "String" ist dann "lower bound".
Um das Lesen mit get() habe ich mich bisher kaum gekümmert, aber eben habe ich in derWas bedeutet arbeiten in diesem Fall? Lesen? Schreiben?
API nachgeschaut und kann nicht bestätigen, dass get() Object zurückgibt
Da steht bei List "E get(int index)" wobei E als Typparameter der List erklärt wird und
der wäre meines Erachtens eben das was innerhalb < > steht.
Ja, so wie ich es verstanden alle möglichen SuperTypen von Integer also auch Object.List<? super Integer> superOfIntegers -> schreiben kann ich nur Integer ... lesen kann ich jedoch Object (da ja alle möglichen SuperTypen von Integer)zurück kommen können...
Nun ja, mein anfängliches Problem ist noch nicht gelöst.
Ich bin über die Seite von Nikos P.
//http://nikojava.wordpress.com/2008/1...jp-generics-25
zu der anfänglichen Frage gestoßen.
List<Number> list10 = null;
List<Integer> list11 = null;
list11 = list10; // Compiler-Fehler incompatible types
list10 = list11; // Compiler-Fehler incompatible types ==> ES GILT OFFENBAR KEINE IS-A BEZIEHUNG !
Wegen dem vorgenanten schließe ich, dass IS-A Relation bei generics keine Rolle spielt.
Ich denke, dass
OK ist, ist weil eine der drei Möglichkeiten genau passt, da die IS-A Relation offenbar bei generics keine Rolle spielt. Das meine ich auch mitCode java:1 2 3
List<Number> list14 = null; List<? super Integer> list15 = null; list15 = list14; // Zeile 4, OK
Aber beiCompiler großzügig bzw. wohlwollend entscheidet
gäbe es auch mindestens eine Kombination die OK ist, aber es gibt hier auch den Compiler-Fehler "incompatible types..." womit die Theorie "großzügige Entscheidung" ( soll heissen: wenn wenigstens eins passt, dann kein Compiler-Fehler )Code java:1 2 3
Queue<? extends Number> q1 = null; Queue<? super Integer> q2 = null; q1 = q2 // Compiler-Fehler: incompatible types
auch nicht stimmen kann!
Deshalb bin ich erstmal immer noch ratlos.
Viele Grüße
Steve222
-
@steve222
Verstehe ich das richtig? <? super Integer> darf super typen aufnehmen.
und du willst eine Collection vom Typ Number in diese Collection vom Typ <? super Integer> schreiben.
Number ist doch super typ von Integer. Oder verstehe ich hier gerade alles falsch?
-
19.02.11 23:43 #7
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.885
- Blog-Einträge
- 29
Hallo,
da hast du natürlich recht.gut, dass Du pragmatisch daran gehst und Lesen und Schreiben ausprobierst, aber dennoch sollten die Begrifflichkeiten geklärt werden.
Genau.Wie Du mitteilst geht es darum jeweils Collection-Objekte auf auf einen bestimmten
Typ, oder auf einige wenige Typen festzulegen.
Das sollte man aber nicht außen vor lassen, denn Collections werden IMHO deutlich öfter gelesen als geschrieben.Um das Lesen mit get() habe ich mich bisher kaum gekümmert...
Ja genau und was ist dieses E in dem Szenario?... aber eben habe ich in der
API nachgeschaut und kann nicht bestätigen, dass get() Object zurückgibt
Da steht bei List "E get(int index)" wobei E als Typparameter der List erklärt wird und
der wäre meines Erachtens eben das was innerhalb < > steht.
Richtig: ? super Integer und welchen Typ haben wir dann? -> (? super Integer) und das wäre dann
allgemein: Object. Etwas anderes kannst du dann nämlich nicht definieren. Das gäbe dann einen
Compilefehler.
Code java:1 2
List<? super Integer> superOfIntegers = ... Object value = superOfIntegers.get(0);
Hier liegt wie schon beschrieben ein wichtiger Unterschied:
Code java:
Java Generics sind nicht Covariant... sprich eine List<Integer> ist keine List<Number>, noch nichtmal eine List<Object>
Siehe auch:
http://www.fh-wedel.de/~si/seminare/...s/genjava3.htm
Code java:1 2
List<Integer> ints = null; List<Object> os = ints; //Compiler error
Mit Wildcards kann man diesen Umstand etwas auflösen.
Code java:1 2
List<Integer> ints = null; List<? extends Object> os = ints; //ok
Code java:1 2 3
Queue<? extends Number> q1 = null; Queue<? super Integer> q2 = null; q1 = q2 // Compiler Fehler
Hier mal noch zwei Beispiele zu deinem Queue-Fall:
Code java:1 2 3 4
Queue<? extends Number> q1 = null; //q1 garantiert numbers -> Number peek(), akzeptiert: ****? Queue<? super Integer> q2 = null; //q2 garantiert objects -> Object peer(), akzeptiert: Integer q1 = q2 // geht nicht: etwas was Objects garantiert kann nicht plötzlich Numbers garantiert... deshalb Compilerfehler q2 = q1; // geht auch nicht
Was gehen würde:
Code java:1 2 3 4
Queue<Number> q1 = null; //q1 garantiert numbers -> Number peek(), akzeptiert: Number void add(Number) Queue<? super Integer> q2 = null; //q2 garantiert objects -> Object peer(), akzeptiert: Integer //q1 = q2 // geht nicht: etwas was Objects garantiert kann nicht plötzlich Numbers garantiert... deshalb Compilerfehler q2 = q1; // geht
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
Eine Liste wie list<? super Integer> nimmt Integer, Number und Object auf. Warum? Weil Object super Klasse von Number und Number super Klasse von Integer ist. Und <? super Integer> besagt das die Liste Integer und dessen super Klassen aufnimmt.
Und solange rechts etwas steht was nur einem Kriterium erfüllt funktioniert die Zuweisung.
Während list<Integer> besagt das nur Vollwertige Integer aufgenommen werden.
Was bedeutet in unserem Fall Vollwertig? Vollwertig bedeutet das das der Typ der aufgenommen wird exakt mit den Vorgaben Übereinstimmen muss. Integer IS-A Number, aber Number IS-Not A Integer. und weil Number kein Integer ist kann eine Zuweisung von list<integer> = list<Number> nicht funktionieren.
Ich versuche es mal zu verdeutlichen
die Prüfung des Compilers bei <? super Integer> ist ob die liste die gegeben wird einem der super Typen entspricht
also Number || Integer || Object, solange nur eins true ergibt wird die gegebene Liste Akzeptiert.
die Prüfung bei list<Integer> verlangt nach Integer und Prüft nur das ab und solange es false ergibt wird nichts angenommen.
-
Hallo Tom,
Du schriebst:
[Ja genau und was ist dieses E in dem Szenario?
Richtig: ? super Integer und welchen Typ haben wir dann? -> (? super Integer) und das wäre dann
allgemein: Object. Etwas anderes kannst du dann nämlich nicht definieren. Das gäbe dann einen
Compilefehler.
Auch wenn ich wohl weniger weiss bzgl. Java als Du... ]
genau die Stelle:
Und genau das habe ich bisher anders aufgefasst:...das wäre dann allgemein: Object...
<? super Integer> steht, denke ich, für Integer oder Number oder Object.
Also "Integer" ist hier lower bound und somit sind Integer
und sene Superklassen
als Typ erlaubt.
Im Moment hilft mir das alles zu meiner anfänglichen Frage nicht wirklich weiter, denn es sind einige
Wiederholungen und auch Fakten, die mir bereits seit längerem belkannt sind.
wie z.B.
Java Generics sind nicht Covariant... sprich eine List<Integer> ist keine List<Number>, noch nichtmal eine
List<Object> Ich schrieb, dass IS-A Relationen bei generics keine Rolle spielen.
Was mir hoffentlich was nutzt, ist die Anregung zum rumpropieren mit Lesen und Schreiben.
Aber da bin ich im Moment auf etliches gestoßen was ich einfach nicht einordnen kann
wie z.B.
Code java:
Für mich bedeutet Queue<? extends Number> q1 = null; dass in q1
Integer-Objekte hinzugefügt werden können, weil ...Integer extends Number..
Integer IS-A Number
upper bound ist hier Number aber Number-Objekte gehen nicht, weil es die garnicht, weil abstract,
gibt.
Das was Du am Ende schreibst ist prinzipiell das gleiche (jetzt nur mit queue anstatt List) was ich ganz am Anfang geschrieben habe, oder nicht? Ich weiß nicht genau wie Du Dich selbst einschätzt bezüglich generics Es gibt da divergente Hinweise...Sofern Du bei generics Lücken hast kannst Du diese aufgrund Deiner Erfahrung bestimmt recht bald schließen.
Ich habe vor IMMER zu verstehen, warum ein Compilerfehler auftritt.
Es nur in den meisten Fällen zu wissen, reicht mir nicht.
Die "wildcards with an upper bzw. lower bound" geben mir gerade in der praktischen
Verwendung (Lesen, Schreiben) im Moment noch mehr Rätsel auf.
Viele Grüße
Steve222
-
20.02.11 21:51 #10
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.885
- Blog-Einträge
- 29
Hallo,
ich denke das du hier deine Antwort findest:
http://www.torsten-horn.de/techdocs/java-generics.htm
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
Ähnliche Themen
-
Generics:Typverträglichkeit bei <? super Integer>
Von Steve222 im Forum Java GrundlagenAntworten: 4Letzter Beitrag: 20.02.11, 03:42 -
Generics Syntax
Von Lastlord im Forum JavaAntworten: 5Letzter Beitrag: 03.11.10, 08:50 -
Generics
Von bRainLaG im Forum JavaAntworten: 3Letzter Beitrag: 09.12.09, 12:42 -
Generics
Von Conkerchen im Forum Algorithmen & Datenstrukturen mit JavaAntworten: 1Letzter Beitrag: 31.05.09, 19:18 -
Casten von Generics
Von dr-oetker im Forum JavaAntworten: 2Letzter Beitrag: 13.04.07, 09:37





Zitieren

Login





