Skip to content

Latest commit

 

History

History
187 lines (148 loc) · 4.52 KB

Kap.12.adoc

File metadata and controls

187 lines (148 loc) · 4.52 KB

Die aktuellen Fragen zu diesem Kapitel haben wir beschränkt mit Rücksicht auf unsere Erstsemester, für die vorerst "einfache" Generics genügen mögen.

  1. Wir nehmen aus dem Kapitel 12 das Unterkapitel 12.4 (Wildcards) raus.

  2. Wir ignorieren die Verwendung von extends bei der Angabe von Typparametern.

Frage

Eine Klasse Container soll im Konstruktor einen beliebigen Typ als Inhalt (content) aufnehmen können. Schreiben Sie den Code ohne Object zu verwenden.

Antwort
class Container<T> {
  T content;
  Container(T content) {
    this.content = content;
  }
}
jshell> new Container<Integer>(3)
$20 ==> Container@17579e0f

Frage

Aus unerfindlichen Gründen bietet die Java-API keine Tupel-Klasse an. Wie würde so eine Klasse aussehen, die zwei Variablen von beliebigem Typ enthalten kann?

Antwort
class Tupel<T,U> {
  T car; // das ist ein historischer Name
  U cdr; // das ist ein historischer Name
  Tupel(T first, U second) {
    car = first;
    cdr = second;
  }
}

Frage

Legen Sie eine neue ArrayList an, die ausschließlich aus Ganzzahlen besteht.

Antwort
new ArrayList<Integer>();

Frage

Was ist ein Typparameter?

Antwort

 — TODO — 

Frage

Deklarieren und initialisieren Sie eine Variable a, die ausschließlich eine ArrayList von boolschen Werten aufnehmen kann. Die Lösung muss so kurz wie möglich sein.

Antwort

Entweder Sie deklarieren a vom Typ ArrayList:

ArrayList<Boolean> a = new ArrayList<>();

Oder, was Sie oft sehen, Sie nehmen das List-Interface als Typ, der durch die ArrayList implementiert wird.

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

Frage

Wie lautet die Syntax für eine generische Methode?

Antwort
<T extends I> Rückgabetyp methodName(parameters) { ... }

Frage

Inwiefern hebelt die Definition <T> T giveMeWhatIWant() { …​ } das Typsystem von Java aus?

Antwort

Diese Methode muss eine Implementierung bieten, die für jeden Typ passen muss.

Frage

Wie sieht schematisch die Syntax einer generischen Klasse aus? Reduzieren Sie die Syntax auf das Notwendigste.

Antwort
class Name<TypParameter, ...> { ... }

Frage

class A<T> { void foo(T x) {} }
A myA = new A();

Kann man das schreiben? Welcher Typ wird für den Typparameter T eingesetzt?

Antwort

Der allgemeinste Typ hier, der implizit eingesetzt wird, ist Object. Aber: Das ist kein guter Programmierstil.

Frage

class Foo<T> {
  int getLength(T value) {
    return value.length();
  }
}
Foo<String> f = new Foo<>();
f.getLength("abc");

Oh Schmerz! Weswegen?

Antwort

Man kann nicht davon ausgehen, dass value, dessen Typ über T frei gewählt werden kann, eine length-Method hat.

Frage

class Bar<Blubber> { Blubber x; } Problem?

Antwort

Nein, kein Problem. Es ist unüblich, lange Namen für Typparameter zu wählen. Per Konvention verwendet man nur einzelne Großbuchstaben.

Frage

Man kann eine Klasse als MyClass<T extends Number> deklarieren, ist auch MyClass<T implements AutoCloseable> erlaubt?

Antwort

Das implements ist in der Syntax nicht vorgesehen, ist nicht erlaubt.

Frage

class ICanHazGenerics<E extends Comparable> {} Und schon gibt’s was auf die Finger. Was ist der Grund?

Antwort

Man sollte den Typ für Comparable<???> angeben.

Frage

class A<T extends B> {} Kann man A<B> value = new A<B>(); schreiben? Gilt also B extends B?

Antwort

Die Klasse B als T kann das, was B kann, das meint <T extends B>.

Frage

List<? extends Number> lst = new ArrayList<>();
lst.add(new Integer(8));

Die zweite Zeile produziert einen Fehler. Können Sie sich vorstellen, warum man einer List<? extends Number> keinen Integer hinzufügen kann?

Antwort

Man könnte mal einen Integer der Liste hinzufügen, mal einen Double. Der Compiler kann diese Entscheidung nicht auflösen.