Dez 03

So, heute die nächste Art von Wildcards:

public static void checkStatus_list (List <? super Buchhalter> a){ … }

Dies bedeutet, dass alle Elemente vom Typ Buchhalter oder deren Oberklassen übergeben werden können.

Auch hier ist ein Cast notwendig, um durch die Elemente zu gehen und die jeweiligen Methoden aufzurufen:

for (Object x : a)
System.out.println(((Angestellter)x).getName());

Hier ist aber Vorsicht geboten; es muss zur Oberklasse gecasted werden, da  ansonsten einen Laufzeitfehler (keinen CompilerFehler) auftritt.

Das direkte hinzufügen funktioniert in unserem Beispiel nur beim Typ Buchhalter:

a.add(new Buchhalter());

Es können zwar alle möglichen Elemente vom Typ Buchhalter oder deren Oberklassen übergeben werden, eingefügt werden kann aber nur der aktuelle Typ, da ein heruntercasten nie möglich ist.

Tagged with:
Dez 01

Heute wollen wir die Methode checkStatus_list erneut abändern:

public static void checkStatus_list (List <? extends Angestellter>  a){ … }

Obwohl Serializable ein Interface ist, muss in diesem Falle extends benutzt werden, alles andere ergibt einen CompilerFehler!

Um durch die Objekte durchgehen und überschriebene Methoden aufrufen zu können, ist kein Cast notwendig:

for (Angestellter b : a)
System.out.println(“List yyy ” +b.getName());

Das Hinzufügen weiterer Elemente innerhalb der Methode ist nicht möglich.

Weitere Funktionen dieser Wildcard-Art werden im SCJP nicht abgefragt, deswegen werde ich fürs Erste nicht weiter darauf eingehen.


Tagged with:
Nov 28

Es mag vielleicht die ein oder andere Situation geben, in der man doch die (bis jetzt nicht-) vorhandenen Möglichkeiten, die z.B. Arrays bezüglich Methodenaufrufen bieten, nutzen möchte. Hierfür gibt es eine Art Workaround, gehen wir mal wieder von einer unserer bereits diskutierten Methoden aus:

public static void checkStatus_list (List <Angestellter> a) { … }

Diese kann mit einer sogenannten Wildcard versehen werden und sieht dann so aus:

public static void checkStatus_list (List <? extends Angestellter> a) { … }

Eine List von Buchhalter kann jetzt problemlos übergeben werden:

List <Buchhalter> a =new ArrayList<Buchhalter>();
a.add(new Buchhalter());
a.add(new Buchhalter());

checkStatus_list(a); // kein Compilerfehler!

die mit der Wildcard veränderte Methode nimmt die List Buchhalter problemlos auf. So einfach, wie es momentan aussieht, ist der Workaround leider nicht.

a.add(new Buchhalter());

ergibt z.B. innerhalb der Methode checkStatus_list einen Compilerfehler!


Tagged with:
Nov 25

Das die Zuweisung

a.add(new Buchhalter());
a.add(new Verkäufer());

in unserem vorherigen Beispiel funktioniert, haben wir ja schon vor ein paar Tagen durchgesprochen.

Gehen wir mal davon aus, dass wir überschriebene Methoden haben:

class Buchhalter extends Angestellter{String getName(){ return(“Buchhalter”);}}
class Verkäufer extends Angestellter{ String getName(){ return (“Verkäufer”);}}

Diese Funktionen können direkt und ohne Probleme augerufen werden, weil ja zur Laufzeit nicht mehr zwischen Array und ArrayList unterschieden wird:

System.out.println(a.get(0).getName()); // Ausgabe: Buchhalter
System.out.println(a.get(1).getName()); //Ausgabe: Verkäufer

Tagged with:
Nov 22

So, aufgewärmt sind wir schon für die Methodenaufrufe, heute wollen wir noch tiefer einsteigen:

Dieses Mal gehen wir von etwas anderen Definitionen aus:

List <Buchhalter> a = new ArrayList <Buchhalter>();
a.add(new Buchhalter());
a.add(new Buchhalter());

Buchhalter i [] = {new Buchhalter(), new Buchhalter ()};

Die Methoden bleiben gleich:

public static void checkStatus_array (Angestellter [] a){  … }
public static void checkStatus_list (List<Angestellter> a){ … }

Auch hier rufen wir wieder die jeweiligen Funktionen auf:

checkStatus_list(a); // CompilerFehler
checkStatus_array(b); // funktioniert einwandfrei

In beiden Fällen wird “Buchhalter” übergeben und der Typ “Angestellter aufgenommen.

Bei Arrays haben wir auch schon gelernt, das dies problemlos funktioniert; bei List funktioniert dies leider nicht. Es muss also immer der genaue List-Objekt-Typ übergeben werden, ein Cast findet nicht statt.

Achtung; innerhalb des List-Types kann bei der Zuweisung von Objekten durch die Methode add(Objekt) ein Cast statt finden, nicht aber beim Aufruf von Methoden!

Tagged with:
Nov 19

Gehen wir mal von 2 ähnlichen Methoden aus:

public static void checkStatus_array (Angestellter [] a){  … }
public static void checkStatus_list (List<Angestellter> a){ … }

Eigentlich müssten diese auch ähnlich arbeiten, oder?
Hier ersteinmal die Definitionen:

List <Angestellter> a= new ArrayList <Angestellter>();
a.add(new Buchhalter());
a.add(new Verkäufer());

Angestellter b [] = {new Buchhalter(), new Verkäufer ()};

Der Aufruf der einzelnen Funktionen funktioniert einwandfrei:

checkStatus_list(a);
checkStatus_array(b);

Ein gegenseitiger Aufruf funktioniert nicht:

checkStatus_list(b);
checkStatus_array(a);

Tagged with:
Nov 16

Erst einmal eine etwas ausführlichere Wiederholung bevor wir wieder in die Besonderheiten von generics einsteigen; gehen wir mal von folgenden Deklarierungen aus:

Angestellter () { … }
Buchhalter extends Angestellter () { … }
Verkäufer extends Angestellter () { … }

Wie auch bereits hier erläutert, ist ein Cast einer Subklasse in die Überklasse problemlos möglich.

Angestellter a = new Buchhalter ();
Angestellter b = new Verkäufer ();

Dies gilt genauso für Arrays:

Angestellter [ ] c = {new Buchhalter(), new Verkäufer() };

In jedem dieser Beispiele werden im Falle einer Überschreibung auch jeweils die Methoden der Sub-Klassen (Buchhalter oder Verkäufer) aufgerufen.

Für Collections funktioniert dies nicht

List <Angestellter> b = new ArrayList <Buchhalter>();

Was aber funktioniert, ist die Zuweisung von Sub-Klassen zur Collection der Oberklasse:

List <Angestellter> d = new ArrayList <Angestellter>();
d.add(new Buchhalter());
d.add(new Verkäufer());


Hier wird keine Warnung produziert, der Code arbeitet auch im weiteren Verlauf  einwandfrei.

Tagged with:
Nov 13

Wie wir ja bereits wissen, funktionieren Collections, deren Zuweisung auf das Basis-Objekt erfolgt, einwandfrei:

List <Integer> a= new ArrayList<Integer>();

Die Idee, liegt nahe, das das bei dem Objekt-Typ genauso funktionieren müsste:

List <Angestellter> b = new ArrayList <Buchhalter>();

Ich streiche es direkt mal durch, damit sich niemand was falsches merkt, dies funktioniert nämlich nicht.

Die Regel, die dahinter steckt ist nämlich relativ einfach: Variablendeklaration und Übergabe zum Objekttyp müssen exakt übereinstimmen.

Auch wenn es bei Arrays anders ist (Angesteller []c = new Buchhalter(3); funktioniert z.B. dort), hier funktioniert dies bei Collections leider nicht – bitte nicht im SCJP verwirren lassen.

Tagged with:
Nov 07

Gerade im SCJP ist es wichtig, unterscheiden zu können, ob eine Warnung, ein CompilerFehler oder ein Laufzeitfehler auftritt.

Deswegen hier eine kleine Zusammenfassung:

Compiler-Fehler treten u.a. bei expliziter Zuweisung von nicht erlaubten Werten zu Generics auf

Warnungen treten bei einer Vermischung von (non-)Generics auf, damit der Programmierer hier (falls nötig) Abhilfe schaffen kann.

Laufzeitfehler treten im Verlauf des Programmes auf, z.B. wenn mit einem unerwarteten Wert weitergearbeitet werden soll.

Tagged with:
Nov 03

wir wissen bereits, dass alles, was mit der Vermischung der (nicht-)generischen Collection in Verbindung steht, laufen wird, sofern es (wenn auch mit Warnung) compilierbar ist. Unter diesen Umständen können auch eigentlich nicht erlaubte Objekt-Typen zur collection hinzugefügt werden.

Wie sieht es aber im weiteren Verlauf des Programmes aus? Auch wenn das Objekt wie in unseren Beispielen hinzugefügt werden kann, ist es immer noch ein String und kein Integer. Aus diesem Grunde sind die Probleme vorhersehbar:

List <Integer> a= new ArrayList<Integer>();

a.add(1);
a.add(2);
a.add(3);

Einfügen e = new Einfügen();
e.hinzufügen(a);
// problemloses Hinzufügen eines String-Objektes
e.hinzufügen(a); // problemloses Hinzufügen eines weiteren String-Objektes

a.remove(4);
// auch die Löschung eines String-Objektes ist kein Problem

for (int x= 0; x<a.size(); x++)
System.out.print(a.get(x)+” “);
// Die Ausgabe erfolgt auch problemlos

int z=a.get(3); // die Zuweisung zu einem Int-Wert funktioniert nicht (ClassCastException zur Laufzeit)

Tagged with:
preload preload preload
http://www.wikio.de Blog Top Liste - by TopBlogs.de Blogverzeichnis - Blog Verzeichnis bloggerei.de Bloggeramt.de Software
Webbhotell Top Blogs