Frage von Anonynonymous, 33

Java Frage zu Generics?

Hallo zusammen,

ich habe eine Verständnisfrage zu Java Generics. Ich verstehe das Thema noch nicht so ganz und wollte hiermit einfach mal Fragen, ob ich das bis jetzt einigermaßen Verstanden habe.

Ich habe die Verwendung von Generics für mich in 2 Gebiete unterteilt.

  1. Bei Anwendung von Generics auf Objekten wie z.B. Listen, bieten diese dann Typsicherheit.

Beispiel:

GenericList <Integer> ints = new GenericList<>();

(In der Textvorschau werden mir die Spitzen Pfeile als "& lt;" und "& gt;" angezeigt. Falls es in der Frage nicht durch die eigentlichen Pfeile ersetzt wird, bitte & lt; und & gt; wegdenken und durch Spitze Pfeile ersetzen ;-)

2 . Bei Verwendung in einer Klassendefinition scheint es als Platzhalter für den später eigentlich verwendeten Typ zu fungieren.

public class GenericNode<C> {


GenericNode<C> next;
C content;
...    
 }

Ich habe die Attribute auch noch einmal mit reingenommen.

So ist es mir in dem mir vorliegendem Beispiel bspw. möglich mit

GenericList ints = new GenericList<>();

und

GenericList Strings = new GenericList<>();

trotz der beiden unterschiedlichen Datentypen typsicher zu arbeiten.

Viele Grüße und danke im Voraus für eure Antworten.

VG.

Hilfreichste Antwort - ausgezeichnet vom Fragesteller
von KnusperPudding, Community-Experte für Java, 9

Soweit hast du das richtig verstanden: Der Generics-Ausdruck durch einen Buchstaben ersetzt eine Mögliche Klasse, welche du übergeben kannst. 

- Bei Datentypen etwas vorsichtig sein: Denn es gilt hauptsächlich für Klassen, worunter auch Integer und String fällt. Primitive Datentypen (int, char, double, etc...) sind nicht möglich.

Worin besteht der Vorteil? Wie du richtig erkannt hast, bei List kannst du ausschließlich die genannte Klasse(oder Inerface) anfügen als auch wieder erhalten ohne hier nochmal den Typen abfragen zu müssen. Sowie Klassen, die von dieser Klasse erben, oder jenes Interface Implementieren.

Kommentar von Anonynonymous ,

Vielen Dank für deine Antwort, das hat mir schon sehr geholfen.

Ich habe mir gerade noch einmal die Java Dokumentation dazu angeschaut.

(http://docs.oracle.com/javase/tutorial/java/generics/types.html)

Was mir dazu noch sehr geholfen hat, war die Aussage, dass, wenn man eine generische Version einer Klasse erstellt, alle Objektvorkommen zwar durch ein <T> ersetzen kann, das instanziierte Objekt an sich jedoch einer bestimmten Klasse/Interface zuweisen muss.

Das waren dann auch die 2 "Fälle", die ich oben unterschieden habe. Auch, wenn es wohl keine Fälle gewesen sind ;-)

Ich denke, jetzt habe ich es so langsam, richtig?

Kommentar von KnusperPudding ,

das instanziierte Objekt an sich jedoch einer bestimmten Klasse/Interface zuweisen muss.

Wie 'zuweisen'? 

Was in der Doku steht: "Type Parameter": Damit sind die Klassen, oder "Typen" wie du sie nennen möchtest, gemeint.

Somit kannst du bei  List<E> z.b.: eine Klasse mit angeben:

List<String> list;

Was Wert-Zuweisung mit Instanzen betrifft, so werfen wir mal einen Blick in das Interface List, zur Methode: add.

Diese sieht so aus:

boolean add(E e);

hast du entsprechend bei List mit <String> gesetzt, so akzeptiert die Methode add auch nur String Werte.

Es ist etwas schwierig zu erklären, was dir den 'Vorteil' aufzeigt. Darf ich die Gegenfrage stellen ob du dich schon mit dem Begriff: "Polymorphie" beschäftigt hast?

Beispiel:

List<String> list = new ArrayList();

das würde das ganze nämlich etwas vereinfachen bei der Erklärung wenn du das bei dir als Wissen schon 'abgehakt' hast.

Antwort
von triopasi, 30

Ich erkläre mal am Beispiel C/C++, da ist das ganze etwas einleuchtender.

Dort heißt das ganze einfach template. Im wesentlichen ist ein template eine Schablone für zB eine Klasse oder Methode. Angenommen ich habe eine Methode "method( var)" und rufe diese in meinem C/C++ Code einmal mit einem string und einmal mit einem int als Argument auf, dann generiert der Compiler diese Methode einmal als "method(string var)" und einmal als "method(int var)". Es werden vom Compiler als Klassen/Methoden nach meiner Schablone angelegt.

In Java ist es durch die VM anderst realisiert, aber Prinzip der "Schablone" und wie is genutzt wird ist dasselbe.

Kommentar von triopasi ,

Ich halte die Unterteilung in 2 Arten von Generics für falsch, da Datentypen auch Klassen sind, ist das 1. nur ne konkretere Anwendung vom 2.

Kommentar von Anonynonymous ,

Danke für diene Antwort.

Was mich ein wenig verwirrt ist, dass ich bei den Beispielen für die Listen, die ich oben erwähnt habe bei <Integer> auch nur int variablen einfügen kann und bei <String> auch nur Strings.

Bei den Methoden der Listen kann ich jedoch beide Listen mit den Datentypen <Integer> und <String> ohne Probleme benutzen, was sich meiner Ansicht nach widerspricht.

(Wahrscheinlich tut es das nicht, mir scheint es aber so zu sein).

Deine Aussage deckt sich in etwa mit der Aussage meines Professors, die in etwa lautete "alle vorkommen von Object werden durch String, Integer oder halt ein anderes Objekt ersetzt".

Ich verstehe nur nicht, warum es bei den Listen ausschließlich, die Datentypen zulässt, mit denen die Listen auch deklariert wurden und bei der Verwendung der Methoden der Klasse GenericNode wiederum die Datentypen String UND Integer und bei Bedarf sogar noch weitere.

Kommentar von Anonynonymous ,

Moment mal..

kann es sein, dass es hier gar nicht um den Inhalt der Objekte geht, sondern darum, dass die Listenelemente jeweils den Datentyp "C" innehaben?

Kommentar von triopasi ,

Hast du mal eine Liste selbst programmiert? Wenn nein, probier das mal.

List<int> ist eine Liste ("aus der Vorlage List<>" sozusagen), für den Datentyp int. Jedes Element der Liste sit daher ein int. Deshalb kann man da auch nur int's reinstecken.

"<type> method(type var)" ist die Definition einer generic methode, wenn ich diese dann z.B. mit "<int> method(16)" aufrufe, sage ich erst, welcher Datentyp für <type> eingesetzt werden soll und dann übergebe ich genau diesen Typ. "<int> method("test")" oder "<int> method(1.0f)" würden nicht gehen, da "test" bzw. 1.0f keine int's sind.

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten