From 29d9a4faa83d8761063b260ca2ccf1302e16a5c4 Mon Sep 17 00:00:00 2001 From: denkspuren Date: Sun, 8 Jan 2017 20:54:56 +0100 Subject: [PATCH] Inital auf Github nach Projektwoche --- Fragen/Kap.1.8.adoc | 131 ++++++ Fragen/Kap.10.adoc | 671 +++++++++++++++++++++++++++++ Fragen/Kap.11.adoc | 525 ++++++++++++++++++++++ Fragen/Kap.12.adoc | 223 ++++++++++ Fragen/Kap.14.adoc | 423 ++++++++++++++++++ Fragen/Kap.15.adoc | 242 +++++++++++ Fragen/Kap.18.adoc | 178 ++++++++ Fragen/Kap.2.adoc | 472 ++++++++++++++++++++ Fragen/Kap.3.adoc | 206 +++++++++ Fragen/Kap.4.adoc | 258 +++++++++++ Fragen/Kap.5.adoc | 123 ++++++ Fragen/Kap.6.adoc | 340 +++++++++++++++ Fragen/Kap.8.adoc | 357 +++++++++++++++ Fragen/Kap.9.adoc | 170 ++++++++ Fragen/images/CollectionBilder.jpg | Bin 0 -> 501802 bytes JavaFragen.adoc | 61 +++ makefile | 17 + 17 files changed, 4397 insertions(+) create mode 100644 Fragen/Kap.1.8.adoc create mode 100644 Fragen/Kap.10.adoc create mode 100644 Fragen/Kap.11.adoc create mode 100644 Fragen/Kap.12.adoc create mode 100644 Fragen/Kap.14.adoc create mode 100644 Fragen/Kap.15.adoc create mode 100644 Fragen/Kap.18.adoc create mode 100644 Fragen/Kap.2.adoc create mode 100644 Fragen/Kap.3.adoc create mode 100644 Fragen/Kap.4.adoc create mode 100644 Fragen/Kap.5.adoc create mode 100644 Fragen/Kap.6.adoc create mode 100644 Fragen/Kap.8.adoc create mode 100644 Fragen/Kap.9.adoc create mode 100644 Fragen/images/CollectionBilder.jpg create mode 100644 JavaFragen.adoc create mode 100644 makefile diff --git a/Fragen/Kap.1.8.adoc b/Fragen/Kap.1.8.adoc new file mode 100644 index 0000000..4abde2c --- /dev/null +++ b/Fragen/Kap.1.8.adoc @@ -0,0 +1,131 @@ +== Hello World!: Java-Crashkurs [Kap. 1.8] + +### Frage +`String x = "abc";` Wo ist das `new` zur Instanziierung? + +ifdef::solution[] +.Antwort +Der Ausdruck `"abc"` ist ein Literal, das eine Abkürzende Schreibweise für den Konstruktoraufruf mit `new` darstellt. +endif::solution[] + +### Frage +Wie unterscheidet sich ein Javadoc-Kommentar von normalen Kommentaren? + +ifdef::solution[] +.Antwort +Javadoc-Kommentare können automatisch weiterverarbeitet werden, z.B. von IDEs wie Eclipse oder IntelliJ. Die HTML-API von Java wurde ebenfalls aus den Javadoc-Kommentaren generiert. +endif::solution[] + +### Frage +Was ist ein Schlüsselwort? + +ifdef::solution[] +.Antwort +Ein reservierter Begriff, der nicht für Bezeichner verwendet werden kann, weil er in Sprachkonstrukten gebraucht wird (z.B. `if`, `for`, `class`). +endif::solution[] + +### Frage +Never use Dollars in Javaland. Why? + +ifdef::solution[] +.Antwort +Dollars werden für automatisch generierten Code verwendet. +endif::solution[] + +### Frage +`for(int i=0; i<=10; i++);`. Wo ist das Problem? + +ifdef::solution[] +.Antwort +Die Schleife tut gar nichts, weil der Körper aus einer leeren Anweisung (Semikolon) besteht. +endif::solution[] + +### Frage +Das `;` (Semikolon) beendet eine ___? + +ifdef::solution[] +.Antwort +Anweisung +endif::solution[] + +### Frage +Das `+` bei Strings ist ein ___-Operator + +ifdef::solution[] +.Antwort +Konkatenations-Operator +endif::solution[] + +### Frage +Wenn jede Anweisung mit einem Semikolon beendet werden muss, gilt das auch für `if` oder `while`? + +Bsp.: `if (x < 0); x = 0;` (Was macht dieser Code?) + +ifdef::solution[] +.Antwort +Wenn das `if` greift, wird es von einer leeren Anweisung `;` gefolgt -- insofern bleibt das `if` wirkungslos. Der sich anschließende Ausdruck `x = 0;` wird immer ausgeführt. +endif::solution[] + +### Frage +Warum kann man die Klasse `Math` verwenden, ohne sie vorher zu importieren? + +ifdef::solution[] +.Antwort +Weil sie im Paket `java.lang` definiert ist, das immer importiert wird. +endif::solution[] + +### Frage +Wann kommt ein Punkt `.` vor den Klassennamen? + +ifdef::solution[] +.Antwort +Wenn die Klasse in einem (noch nicht importierten) Paket definiert ist. +endif::solution[] + +### Frage +Auf S.54 steht was zur Option `-encoding`. In welchem Aufgabenblatt gibt es dazu eine Anmerkung? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Auf S.52 unten heißt es: "Java kennt keine Eigenschaften." Auf S.57 unten jedoch: "Über Attribute können Eigenschaften von Objekten gelesen bzw. gespeichert werden." Was ist da los? Ein Widerspruch? + +ifdef::solution[] +.Antwort +Der Begriff "Eigenschaften" ist hier doppelt belegt. Im ersten Satz ist das englische _property_ gemeint, womit ein Sprachkonstrukt bezeichnet wird, das es in Java nicht gibt. Im zweiten Satz geht es tatsächlich um "Eigenschaften" im umgangssprachlichen Sinne, also um Felder von Objekten. Leider werden diese Begriffe nicht immer einheitlich verwendet. +endif::solution[] + +### Frage +`import paket.*;` Was meint der Stern `*` in der `import`-Anweisung? + +ifdef::solution[] +.Antwort +Der Stern importiert alle Klassen in dem jeweiligen Paket. +endif::solution[] + +### Frage +S.59 im Code: `DateTimeFormatter.ofPattern( "EEEE, d. MMMM yyyy" );` Häh? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Warum kann man keine Instanz der Klasse `Math` erzeugen? + +ifdef::solution[] +.Antwort +Der Konstruktor von `Math` ist nicht `public` und damit ist keine Instanz von `Math` erzeugbar. +endif::solution[] + +### Frage +Warum muss man überhaupt `import` verwenden? + +ifdef::solution[] +.Antwort +Weil Klassen in Paketen organisiert sind. Dadurch ist es möglich, nur die Klassen zu laden, die auch benötigt werden. Gäbe es diese Paketorganisation nicht, müsste man außerdem immer aufpassen, dass Namen von eigenen Klassen nicht identisch sind mit dem Namen irgendeiner Klasse irgendwo in der Java-API. +endif::solution[] diff --git a/Fragen/Kap.10.adoc b/Fragen/Kap.10.adoc new file mode 100644 index 0000000..482291f --- /dev/null +++ b/Fragen/Kap.10.adoc @@ -0,0 +1,671 @@ +== Klassen + +[TIP] +==== +Hinweis: Tabelle 10.1, Modifizierer, müssen Sie können. +==== + +Es kam die Frage auf, warum man in einer Klasse überhaupt Felder und Methoden *nicht* `static` machen soll. Hier ein Versuch, unsere Diskussion nachzuzeichnen. + +Wir erstellen eine Klasse `Car` und geben ihr das statische Feld `owner`. Die Besitzerin heiße Lisa. + +---- +jshell> class Car { static String owner; } +| created class Car + +jshell> Car.owner = "Lisa" +$13 ==> "Lisa" +---- + +Lisa hat zwei Autos. Also instanziieren wir zwei Autos. Jedes dieser Autos können wir nach dem Wert des Felds `owner` befragen. + +---- +jshell> Car car1 = new Car() +car1 ==> Car@148080bb + +jshell> car1.owner +$15 ==> "Lisa" + +jshell> Car car2 = new Car() +car2 ==> Car@6e1ec318 + +jshell> car2.owner +$17 ==> "Lisa" +---- + +Nun verkauft mir Lisa eines der Autos -- sie erklärt sich einverstanden, dass ich als neuer Eigentümer ihres zweiten Autos eingetragen werde. + +---- +jshell> car2.owner = "Dominikus" +$18 ==> "Dominikus" +---- + +Weil `owner` eine statische Klassenvariable ist, habe ich Lisa nun auch ihr anderes Auto abgeluchst, dessen Eigentümer ich nun ebenfalls bin. + +---- +jshell> car2.owner = "Dominikus" +$18 ==> "Dominikus" +---- + +Zauberei? Betrug? Mitnichten, es liegt an der statischen Klassenvariablen. Wäre `owner` keine statische Klassenvariable gewesen, dann hätte jedes Auto seinen eigenen Wert für einen Eigentümer speichern können -- und Lisa hätte mir nicht unfreiwillig all ihre Autos abgetreten. Probieren Sie's aus! + +Was lernen wir? Ein statisches Feld enthält einen Wert, den die Klasse speichert und der für alle Instanzen der Klasse gleich ist. Ein "normales", nicht statisches Feld ist eine Variable, die jede Instanz für sich individuell angelegt bekommt. Und genau das möchte Objektorientierung: jeder Instanz eine eigene Umgebung für (nicht statische) Klassenvariablen mitgeben. + +### Frage +Herr Kofler nennt welche Vorteile, die Objektorientierung bietet? + +ifdef::solution[] +.Antwort +// TODO +endif::solution[] + +### Frage +Wann ist eine Klasse *keine* _top level_-Klasse? + +ifdef::solution[] +.Antwort +Wenn sie innerhalb von geschweiften Klammern steht. +endif::solution[] + +### Frage +---- +void foo() { + class StrangeThing { + boolean isStrange = true; + } + StrangeThing thing = new StrangeThing(); + System.out.println(thing.isStrange); +} +---- +Geht das? + +ifdef::solution[] +.Antwort +Das geht. Es handelt sich hier um eine lokale Klassendefinition, die nur innerhalb der Methode `foo` verwendet werden kann. +endif::solution[] + +### Frage +Wie sieht schematisch die Syntax zur Klasse aus? [ohne Annotationen und Generics] + +ifdef::solution[] +.Antwort +---- +[Modifizierer] class Name [extends KlassenName] [implements I1, I2, ...] +---- +endif::solution[] + +### Frage +In einer `.java`-Datei können mehrere Klassen deklariert werden. Allerdings gilt eine Einschränkung, was den Namen der Datei angeht. Welche? + +ifdef::solution[] +.Antwort +Wenn eine der Klassen öffentlich (`public`) ist, muss der Name der Datei dem Namen dieser Klasse entsprechen. +endif::solution[] + +### Frage +Schreibe `class test` und schon ist der Kopf ab, bevor auch nur ein `{` folgt. Warum? [Gemeint ist Ihr Kopf, nicht der der Klassendeklaration :upside_down_face:!) + +ifdef::solution[] +.Antwort +Es sollte `class Test` heißen. Namen von Klassen werden großgeschrieben. +endif::solution[] + +### Frage +Eine _top level_-Klasse darf welche Sichtbarkeiten *nicht* haben? + +ifdef::solution[] +.Antwort +`private` und `protected` sind nicht erlaubt, da eine Toplevel-Klasse sich nicht im Kontext einer anderen Klasse befindet und diese Sichtbarkeiten somit keinen Sinn ergeben. +endif::solution[] + +### Frage +Gibt es in Java das Laufzeitkonstrukt der Klasse? + +ifdef::solution[] +.Antwort +Nicht direkt, man kann nur darauf zugreifen mittels _reflection_ ( `Objektname.getClass()` bzw. `Klassenname.class`). +endif::solution[] + +### Frage +Gibt es in Java das Laufzeitkonstrukt des Objekts? + +ifdef::solution[] +.Antwort +Ja. +endif::solution[] + +### Frage +---- +class Thing { + private class PartOfThing { + String name = "part"; + } +} +---- +Geht das? + +### Frage +Auf welcher Ebene ist die Klasse `class A {}` sichtbar? + +ifdef::solution[] +.Antwort +Auf der Paketebene. Wenn kein Modifizierer vorhanden ist, ist die Klasse _paketsicher_. +endif::solution[] + +### Frage +Was ist eine Klassenvariable? Doch dasselbe wie ein statisches Feld, oder? + +ifdef::solution[] +.Antwort +Für Herrn Kofler sind "Klassenvariablen" einfach nur beliebige Felder, egal ob sie `static` sind oder nicht. Die Terminologie ist hier in der Literatur nicht eindeutig. +endif::solution[] + +### Frage +Klären Sie die Begriffe "Feld" und "Variable". + +ifdef::solution[] +.Antwort +"Felder" sind Variablen, die im Rumpf einer Klasse deklariert werden. +endif::solution[] + +### Frage +---- +class Thing { + public String name; +} +---- +Kann man auf das Feld `name` von anderen Paketen aus zugreifen? + +ifdef::solution[] +.Antwort +Nein, da man auf die Klasse `Thing` nicht aus anderen Paketen zugreifen kann. +endif::solution[] + +### Frage +Im Rumpf einer Klasse können welche Sprachkonstrukte deklariert werden? + +ifdef::solution[] +.Antwort +Methoden, Felder, Klassen, Interfaces und Enums. +endif::solution[] + +### Frage +---- +class Point { + private int x,y; + Point(int x, int y) { this.x = x; this.y = y; } + boolean equals(Point other) { + return this.x == other.x && this.y == other.y; + } +} +---- +Ist der Zugriff auf das private Feld `other.x` erlaubt? + +ifdef::solution[] +.Antwort +Ja, weil die Sichtbarkeit `private` sich auf allen Code innerhalb der Klasse bezieht. Es ist egal, welches Objekt auf das Feld zugreift, so lange der Zugriff aus irgendeiner Methode der Klasse `Point` erfolgt. +endif::solution[] + +### Frage +Was ist mit dem Begriff "paketsicher" gemeint? + +ifdef::solution[] +.Antwort +"Paketsicher" bezeichnet die default-Sichtbarkeit von Klassen und Feldern (wenn kein Sichtbarkeitsmodifizierer angegeben wurde). Auf "paketsichere" Klassen und Felder kann man innerhalb des Pakets zugreifen in dem sie deklariert wurden. +endif::solution[] + +### Frage +Mit welchem Modifizierer kann man die Voraussetzung für einen immutablen (unveränderlichen) Datentyp schaffen? Reicht die Verwendung dieses Modifizierers allein schon aus, um die Immutabilität zu garantieren? + +ifdef::solution[] +.Antwort +Wenn ein Datentyp (eine Klasse) immutabel sein soll, müssen alle ihre Felder `final` sein. Das reicht allerdings noch nicht aus. Zusätzlich müssen alle Felder selbst einen immutablen Datentyp haben, oder es muss sichergestellt werden, dass niemand sonst eine Referenz auf interne Daten der Klasse haben kann. +endif::solution[] + +### Frage +Nennen Sie die einzelnen Schritte, die bei einem Aufruf von `new` ausgeführt werden. + +ifdef::solution[] +.Antwort + +* Speicherplatz für die nicht-statischen Felder der Klasse wird zugeteilt. +* Außerdem wird eine Refenz zu der Klasse angelegt, von der ein Objekt erzeugt werden soll (um z.B. den Code von Methoden nachschlagen zu können). +* Die Felder werden mit `0`, `false` oder `null` initialisiert. +* Der Konstruktor wird aufgerufen. +* Eine Referenz auf das erstellte Objekt wird zurückgegeben. +endif::solution[] + +### Frage +Wie sieht das Schema zum Zugriff auf eine statische Variable bzw. zum Aufruf einer statischen Methode aus? + +ifdef::solution[] +.Antwort +`Klassenname.variablenname` bzw. `Klassenname.methodenname`. +endif::solution[] + +### Frage +Recherchieren Sie: In der OOP-Veranstaltung hatten wir ein Beispiel, in dem wir eine statische Klassenvariable genutzt haben. Worum ging es bei dem Beispiel? Welchen Zweck hatte die statische Klassenvariable? + +ifdef::solution[] +.Antwort +Es ging um eine Klasse `Thing` mit einer ID, die sich in einem statischen Feld merkt, welche IDs schon vergeben wurden. +endif::solution[] + +### Frage +---- +class Point { + int x = 0, y = 0; + Point(int x, int y) { this.x = x; this.y = y; } +} +Point p = new Point(); +---- +Autsch! Warum? + +ifdef::solution[] +.Antwort +Der Default-Konstruktor existiert nur, wenn kein anderer Konstruktor definiert wurde. In diesem Fall gibt es den Konstruktor `Point()` also nicht. +endif::solution[] + +### Frage +Deklarieren Sie eine Klasse, von der keine Objekte erzeugt werden können. + +ifdef::solution[] +.Antwort +`class Math { private Math() {} }` oder `abstract class Thing {}`. +endif::solution[] + +### Frage +Ein Konstruktor ist mit einer Methodendeklaration sehr vergleichbar. Nur: Der Konstruktor hat zwar einen Namen, ihm scheint jedoch der Rückgabetyp zu fehlen. Warum? + +ifdef::solution[] +.Antwort +Der Rückgabetyp eines Konstruktors ist immer die Klasse in der er deklariert wurde. +endif::solution[] + +### Frage +Was sind die Defaultwerte für Felder (Klassenvariablen)? Was sind die Defaultwerte für lokale Variablen? + +ifdef::solution[] +.Antwort +Die Defaultwerte für Felder sind `0` und `false` für primitive Typen bzw. `null` für Referenztypen. Lokale Variablen haben keine Defaultwerte. +endif::solution[] + +### Frage +Warum kann man `finalize` nicht für Aufräumarbeiten verwenden? + +ifdef::solution[] +.Antwort +`finalize` wird aufgerufen, wenn der Garbage-Collector das Objekt löscht. Es ist nicht garantiert, wann oder ob das überhaupt geschieht. +endif::solution[] + +### Frage +Wie ruft man im Konstruktor einen anderen Konstruktor der gleichen Klasse auf? Warum sollte man das überhaupt tun wollen? + +ifdef::solution[] +.Antwort +`this(Parameter);` +endif::solution[] + +### Frage +---- +class A { + int a,b; + A() { + a = 0; + this(0); + } + A(int x) { + a = 1; + b = x; + } +} +---- +Autsch! Warum? + +ifdef::solution[] +.Antwort +Vor dem Konstruktoraufruf `this(0);` darf kein anderer Ausdruck stehen. +endif::solution[] + +### Frage +Im Vorgriff auch das nächste Kapitel: Wie ruft man im Konstruktor den Konstruktor der Oberklasse auf? + +ifdef::solution[] +.Antwort +`super(Parameter);` +endif::solution[] + +### Frage +Was ist die Besonderheit des Interfaces `AutoCloseable`? Welche Methoden deklariert es? + +ifdef::solution[] +.Antwort +Das Interface deklariert nur die Methode `close`. Klassen, die das Interface `AutoCloseable` implementieren, können in einem _try-with-resources_ verwendet werden. +endif::solution[] + +### Frage +Ist `this` eine Variable? + +ifdef::solution[] +.Antwort +Streng genommen nein (`this` ist ein Schlüsselwort), aber man kann es gedanklich wie eine Variable behandeln. +endif::solution[] + +### Frage +Ist es nicht das gleiche, ob eine Klasse jetzt ein `public int x` definiert oder ein `private int x` mit den Methoden `int getX()` und `void setX(int x)`? Wo liegt der Unterschied? + +ifdef::solution[] +.Antwort +Mit den Methoden hat man mehr Kontrolle darüber, was mit dem Feld geschieht (z.B. welche Werte bei einem `setX` zulässig sind, oder welche Variablen tatsächlich hinter einem `getX` steht). +endif::solution[] + +### Frage +Wozu benötigt man `this`? + +ifdef::solution[] +.Antwort +Um einen Konstruktor in einem anderen Konstruktor aufzurufen und um ein Feld von einer lokalen Variable mit gleichem Namen zu unterscheiden. +endif::solution[] + +### Frage +Wenn man sich in den Namensgebungen für Parameter und lokale Variablen diszipliniert, benötigt man dann überhaupt noch `this`? + +ifdef::solution[] +.Antwort +Ja, für den Aufruf eines Konstruktors oder wenn `this` zurückgegeben oder an eine andere Methode übergeben werden soll. +endif::solution[] + +### Frage +Wenn an den Konstruktor "falsche" Werte übergeben werden, empfiehlt es sich mit einer Exception darauf zu reagieren. Welche Exception sollte man wählen, sofern man nicht spezifischer sein kann/möchte? + +ifdef::solution[] +.Antwort +`IllegalArgumentException` +endif::solution[] + +### Frage +Wenn es einen Konstruktor gibt, muss es auch einen Destruktor geben, nicht wahr?! Hat Java einen Destruktor? Begründen Sie Ihre Antwort! + +ifdef::solution[] +.Antwort +Nein, es gibt nur die Methode `finalize`, die aufgerufen wird, wenn der Garbage-Collector das Objekt löscht. (Achtung: Es kann nicht garantiert werden ob und wann das geschieht.) +endif::solution[] + +### Frage +Eine Klasse, die eine `close`-Methode anbietet sollte die Schnittstelle `AutoCloseable` implementieren. Warum? + +ifdef::solution[] +.Antwort +Damit die Klasse mit einem _try-with-resources_ verwendet werden kann. +endif::solution[] + +### Frage +Was ist mit "Settern" und "Gettern" gemeint? + +ifdef::solution[] +.Antwort +Getter und Setter sind Methoden die das Lesen bzw. Schreiben von internen Daten einer Klasse kontrollieren. +endif::solution[] + +### Frage +Was ist damit gemeint, wenn man von einer "Datenklasse" spricht? + +ifdef::solution[] +.Antwort +Eine "Datenklasse" tut nichts anderes als Werte zu speichern. Die Klasse hat dann nur Felder, Getter und Setter. +endif::solution[] + +### Frage +Wenn Sie Setter- und Getter-Methoden implementieren, dann sollten die Felder wie deklariert sein? + +ifdef::solution[] +.Antwort +`private` +endif::solution[] + +### Frage +Oft sieht man Setter wie `public setName(Typ value) { name = value; }`. Was könnte man daran kritisieren? + +ifdef::solution[] +.Antwort +Dieser Setter macht nicht viel Sinn, da er sich genau so verhält als wäre die Variable `name` öffentlich deklariert. +endif::solution[] + +### Frage +Aufgrund welchen Prinzips der Softwaretechnik werden Setter und Getter begründet? + +ifdef::solution[] +.Antwort +Es geht um das Geheimnisprinzip, das besagt, dass von außen niemand wissen soll, wie die Datenhaltung innerhalb eines Objekts implementiert ist. +endif::solution[] + +### Frage +Welcher softwaretechnische Nutzen steckt vor allem in den Setter-Methoden? + +ifdef::solution[] +.Antwort +Setter ermöglichen es, zu kontrollieren welche Werte für ein Feld erlaubt sind. +endif::solution[] + +// ab hier wieder dh Protokollant. Kap. 10.2 bis Ende + +### Frage +Warum ist der Begriff "Unterklasse" für eine innere Klasse problematisch? + +ifdef::solution[] +.Antwort +Der Begriff "Unterklasse" wird meist für die abgeleitete Klasse einer Oberklasse genutzt. Bitte eine innere Klasse nicht als Unterklasse bezeichnen. +endif::solution[] + +### Frage +[source,java] +---- +class A { + int x; + class B { + int x; + int foo(int x) { + // zähle alle drei mit x benannten Variablen zusammen + } + } +} +---- +Welcher Code muss an der markierten Stelle stehen, um den Wert von allen drei Variablen zusammenzuzählen? Wie unterscheidet man sie voneinander? + +ifdef::solution[] +.Antwort +Wir streuen in die Lösung zum Verständnis ein paar Ausgaben ein. +[source,java] +---- +class A { + int x; + class B { + int x; + int foo(int x) { + System.out.println(x); + System.out.println(this.x); + System.out.println(A.this.x); + System.out.println(B.this.x); + // System.out.println(x); + return x + this.x + A.this.x; // this.x oder B.this.x + } + } +} +---- + +// TODO + +---- +jshell> new A() +$37 ==> A@335eadca + +jshell> $37.new B() +$38 ==> A$B@eec5a4a + +jshell> $38.foo(3) +$39 ==> 3 +---- + +Eine _top level_-Klasse als `static` zu deklarieren ist sinnfrei, da die Klasse an nichts "hängt" und nur Teil eines Pakets ist. +endif::solution[] + +### Frage +`this.name` oder `name.this`, das ist hier die Frage! + +ifdef::solution[] +.Antwort +Beides ist gültig, je nach Kontext. Im zweiten Fall ist `name` jedoch ein Klassenname und sollte eigentlich -- unserer Konvention der Großschreibung für Klassennamen folgend -- als `Name.this` geschrieben werden. +endif::solution[] + +### Frage +---- +AutoCloseable a = new AutoCloseable() { + public void close() { System.out.println("closed"); } +} +---- +Warum geht das, obwohl `AutoCloseable a = new AutoCloseable();` einen Fehler produziert? + +ifdef::solution[] +.Antwort +Hier liegt eine anonyme Klasse vor, die nach ihrer Implementierung sofort instanziiert wird. +endif::solution[] + +### Frage +Kann eine anonyme Klasse einen Konstruktor haben? Warum, oder warum nicht? + +ifdef::solution[] +.Antwort +Wenn es keinen Namen für die Klasse gibt, sie ist ja anonym (= hat keinen Namen), kann man keinen Konstruktor deklarieren. +endif::solution[] + +### Frage +[source,java] +---- +class A { + static int b; + class C { + static int d; + } +} +---- +Sie dürfen _eine_ Sache streichen, damit der Code gültig wird. + +ifdef::solution[] +.Antwort +`C` ist eine lokale Klasse, sie darf keine statischen Members haben. Streiche `static` bei `int d`. +endif::solution[] + +### Frage +Erzeugen Sie eine anonyme Unterklasse von `java.awt.Point`, die die Methode `toString` so überschreibt, dass die String-Repräsentation jetzt einfach der mathematischen Schreibweise `(x, y)` entspricht. Wie können Sie beim Erzeugen des Objektes dieser Klasse die Koordinaten `x` und `y` übergeben? + +ifdef::solution[] +.Antwort +[source,java] +---- +java.awt.Point p = new java.awt.Point() { + public String toString() { + return "(" + x + ", " + y + ")"; + } +} +---- +Die anonyme Klasse ist eine Unterklasse von `java.awt.Point`. + +---- +jshell> java.awt.Point p = new java.awt.Point() { + ...> public String toString() { + ...> return "(" + x + ", " + y + ")"; + ...> } + ...> } +p ==> (0, 0) + +jshell> p.x = 10 +$41 ==> 10 + +jshell> p +p ==> (10, 0) +---- +endif::solution[] + +### Frage +---- +Object obj = new Object() { + public void myFancyNewMethod() { /* do stuff */ } +} +---- +Macht das Sinn? + +ifdef::solution[] +.Antwort +Die Optik verstellt Ihnen hier vermutlich den Blick. `new Object()` ist eine anonyme Klasse, die eine Unterklasse von `Object` ist. Der Typ von `obj` ist hingegen vom Typ `Object`. Wenn man mit `obj` eine Methode wie `myFancyNewMethod` aufrufen will, beginnt die Suche nach der Methode im Typ `Object`, nicht in der anonymen Unterklasse! Die Methode ist also sinnfrei. +endif::solution[] + +### Frage +Eine Instanz einer anonyme Klasse kann nur auf bestimmte Variablen des Kontextes zugreifen, in dem sie erzeugt wurde. Welche Variablen sind das? + +ifdef::solution[] +.Antwort +Variablen müssen `final` sein. +endif::solution[] + +### Frage +Definieren Sie, was _effectively final_ heißt? + +ifdef::solution[] +.Antwort +Eine Variable ist "_effectively final_", wenn sie zwar nicht als `final` deklariert ist, der Compiler aber eine Deklaration mit `final` zulassen würde. +endif::solution[] + +### Frage +`AutoCloseable a = () -> System.out.println("auto");` Wie nennt man so etwas? + +ifdef::solution[] +.Antwort +Das ist ein Lambda-Ausdruck, erkennbar am Pfeil `->`. +endif::solution[] + +### Frage +---- +String message = "foo"; +AutoCloseable a = new AutoCloseable() { + public void close() { System.out.println(message); } +}; +message = "bar"; +---- +Alles in Butter, oder doch nicht? + +ifdef::solution[] +.Antwort +Das `message` nicht _effectively final_ ist, darf die anonyme Klasse nicht auf `message` zugreifen. +endif::solution[] + +### Frage +---- +class A { + static int b; + class C { + static int d; + } +} +---- +Sie dürfen eine Sache ergänzen, damit der Code gültig wird. + +ifdef::solution[] +.Antwort +Die Klasse `C` muss um ein `static` ergänzt werden. +endif::solution[] + +### Frage +Warum sind laut Herrn Kofler statische innere Klassen gar keine "inneren Klassen" im eigentlichen Sinne? + +ifdef::solution[] +.Antwort +Die "innere" Klasse ist wie eine eigenständige Klasse behandelbar. +endif::solution[] + +### Frage +Kann man eine Klasse mit dem qualifizierten Namen `A.B.C` definieren? Wenn ja, wie? (Die Punkte sind Teil des Namens.) + +ifdef::solution[] +.Antwort +Man kann es machen. In einer Klasse `A` ist eine Klasse `B`, in der sich eine Klasse `C` befindet. +endif::solution[] diff --git a/Fragen/Kap.11.adoc b/Fragen/Kap.11.adoc new file mode 100644 index 0000000..55ac14f --- /dev/null +++ b/Fragen/Kap.11.adoc @@ -0,0 +1,525 @@ +== Vererbung und Schnittstellen + +Zu Beginn zwei Beispiele zur Polymorphie. Das Wort "Polymorphie" setzt sich aus zwei Teilen zusammen: _poly_ für "viele" (sie kennen vielleicht das Wort "Polyphonie" als Mehrstimmigkeit) und _morph_ für "Gestalt"; Polymorphie ist die Mehrgestaltigkeit. In der Objektorientierung ist damit gemeint, dass sich ein Objekt je nach Art der Gestalt (seinem Typ entsprechend) angepasst auf einen Methodenaufruf verhält. + +Das Codebeispiel: Menschen (_humans_) sprechen anders als Tiere (_animals_). Im Beispiel ist eine Oberklasse nötig, um in einem Array sowohl Instanzen von `Human` wie auch von `Animal` aufnehmen zu können. + +[source,java] +---- +class Being { + String say(String text) { + return this.getClass().getName() + " says "; + } +} + +class Human extends Being { + String say(String text) { + return super.say(text) + text; + } +} + +class Animal extends Being { + String say(String text) { + return super.say(text) + "nothing (can't talk)"; + } +} + +Being[] beings = { new Human(), new Animal(), new Animal() }; +for(Being b : beings) System.out.println(b.say("good morning")); +---- + +Eine Alternative dazu definitert ein Interface namens `Talker`. Nun können die Klassen nicht auf eine gemeinsame Implementierung über die Oberklasse zugreifen; es besteht -- was durchaus von Vorteil ist -- auch gar keine Notwendigkeit mehr, eine Oberklasse einzuführen. + +[source,java] +---- +interface Talker { + String say(String text); +} + +class Human implements Talker { + public String say(String text) { + return "Human says " + text; + } +} + +class Animal implements Talker { + public String say(String text) { + return "Animal says nothing (can't talk)"; + } +} + +Talker[] talkers = { new Human(), new Animal(), new Animal() }; +for(Talker t : talkers) System.out.println(t.say("good morning")); +---- + +Im ersten Fall der Polymorphie ist den "vielen Gestalten" eine Oberklasse gemeinsam (sie definiert, was die Gestalt _ist_), im zweiten Fall ist den "vielen Gestalten" eine Schnittstelle gemeinsam (sie definiert, was die Gestalt _kann_), die jede teilhabende Klasse für sich implementiert. + +[TIP] +==== +Hinweis zu Kap. 11.2: Sie müssen all die Methoden kennen, die `Object` hat und vererbt. Von `notify`, `notifyAll` und `wait` müssen Sie nur wissen, dass es sie gibt. Das Verständnis dazu erschließt sich erst, wenn wir uns mit Threads beschäftigen [nicht dieses Semester]. +==== + +[TIP] +==== +Mehr zu Hashcodes können Sie z.B. nachlesen unter https://de.wikipedia.org/wiki/Hashfunktion. Hashcodes begegnen Ihnen im Informatik-Alltag immer wieder. +==== + +[TIP] +==== +Tabelle 11.1 (Schnittstellenübersicht) ist Gold wert! Lernen. +==== + +### Frage +Wenn Sie `class A extends B` sehen, wissen Sie, dass `B` was an `A` vererbt? + +ifdef::solution[] +.Antwort +Nur wenn es etwas zu vererben gibt, Dinge die `private` sind werden nicht vererbt. +endif::solution[] + +### Frage +Wenn das hier geht `Object getSelf() { return this; }`, geht dann auch das `Object getSelf() { return super; }`? + +ifdef::solution[] +.Antwort +`super` wird nur verwendet zum Aufruf eines Konstruktors oder zum Zugriff auf Variablen und Methoden. `super` alleine verweist aber nicht auf eine Instanz. +endif::solution[] + +### Frage +Ordnen Sie (siehe letztes Beispiel) die Begriffe `A` oder `B` zu: + +* Oberklasse +* Unterklasse +* abgeleitete Klasse +* Subklasse +* generalisierende Klasse +* spezialisierende Klasse +* Basisklasse + +ifdef::solution[] +.Antwort +`A` ist die Unterklasse, abgeleitete Klasse, Subklasse oder spezialisierende Klasse. `B` ist die Oberklasse, Basisklasse, (Superklasse) oder generalisierende Klasse. +endif::solution[] + +### Frage +Wann ist die Implementierung eines eigenen Konstruktors in einer abgeleiteten Klasse _nicht_ optional? + +ifdef::solution[] +.Antwort +Beispiel: +---- +class Super { + Super(int x) { + ... + } +} +class Sub extends Super { + Sub() { + // hier würde implizit super() aufgerufen + // dieser Konstruktor existiert aber nicht + // => es muss explizit super(int) aufgerufen + // werden + } +} +---- +endif::solution[] + +### Frage +Wenn man eine Methode überschreibt, dann ist die Verwendung einer Annotation üblich. Welcher? + +ifdef::solution[] +.Antwort +`@Override` +endif::solution[] + +### Frage +Eine Method überladen und sie überschreiben ist nicht dasselbe. Erkläre den Unterschied! + +ifdef::solution[] +.Antwort +Eine Methode _überladen_ heißt, eine weitere Variante der Methode mit gleichem Namen aber unterschiedlicher Anzahl von Parametern oder unterschiedlichen Parametertypen zu deklarieren. + +Eine Methode _überschreiben_ heißt, in einer Unterklasse eine Methode mit gleicher Signatur (Name + Anzahl und Typ der Parameter) wie in der Oberklasse zu deklarieren. +endif::solution[] + +### Frage +---- +class A { int method(int i) { return i+1; } } +class B extends A { int method() { return 2; } } +---- + +Überschreibt `B` die Methode von `A`? Oder überlädt `B` die Methode? + +ifdef::solution[] +.Antwort +Das ist ein Beispiel für überladung, da die Methoden nicht die gleiche Anzahl von Parametern haben. +endif::solution[] + +### Frage +Mit welchem Schlüsselwort kann auf Members (Felder und Methoden) der Oberklasse zugegriffen werden? + +ifdef::solution[] +.Antwort +`super` +endif::solution[] + +### Frage +Wie Sie wissen, ist jede Klasse abgeleitet von `Object`. Wenn Sie Code wie `class A { }` sehen, welche Ergänzungen daran nimmt der Compiler vermutlich vor? + +ifdef::solution[] +.Antwort +`class A extends Object { }` +endif::solution[] + +### Frage +Kann eine abstrakte Klasse einen Konstruktor haben? + +ifdef::solution[] +.Antwort +Ja, sie können nur nicht mit `new` aufgerufen werden. In einer Subklasse können Sie aber mit `super(...)` verwendet werden. +endif::solution[] + +### Frage +Wenn ich etwas `super(...)` machen will, wohin damit? + +ifdef::solution[] +.Antwort +In die erste Zeile des Konstruktors der abgeleiteten Klasse. +endif::solution[] + +### Frage +Ich möchte gerne den Konstruktor der Ober-Oberklasse aufrufen. Wie geht das? + +ifdef::solution[] +.Antwort +Direkt geht das nicht, man kann nur auf die direkte Superklasse zugreifen und die muss dann wieder ihre Superklasse aufrufen. +endif::solution[] + +### Frage +Hans deklariert eine Klasse als `final`, Hannah als `abstract`. Was hat Hans mit der Klasse vor, was Hannah? + +ifdef::solution[] +.Antwort +Hans will, dass man von der Klasse nicht erben kann. Hannah will, dass man von der Klasse erben _muss_. +endif::solution[] + +### Frage +Hannah deklariert eine Methode als `final`, Hans als `abstract`. Woran muss Hans denken, was Hannah egal sein kann? Und was kann Hans sein lassen, was Hannah wiederum tun muss? + +ifdef::solution[] +.Antwort +Hans muss die Klasse als `abstract` deklarieren, Hannah muss im Gegensatz zu Hans die Methode implementieren. +endif::solution[] + +### Frage +---- +class A { int x; } +class B extends A { void foo() { x += 1; } } +class C extends A { void foo() { x *= 2; } } +A obj = new B(); +obj.foo(); +---- + +Wie kann man diesen Code retten? + +ifdef::solution[] +.Antwort +Entweder man ändert die letzte Zeile auf `((B) obj).foo()` und castet damit `obj` auf einen Typ der tatsächlich die Methode `foo` hat, oder man macht `A` abstrakt und deklariert die `foo` als abstrakte Methode in `A`. +endif::solution[] + +### Frage +---- +class A { + void m() { System.out.println("mA"); } +} + +class B extends A { + void m() { System.out.println("mB"); } +} +---- + +Nun: `A a = new B()` bzw. `B a = new B()`. Was liefert in jedem der Fälle `a.m()` auf der Konsole? + +ifdef::solution[] +.Antwort +In beiden Fällen wird `mB` ausgegeben. Der Typ der Variablen entscheidet nicht darüber, welche Methode aufgerufen wird, sondern der Typ des Objektes das sich in der Variablen befindet. + +Würde man die Methode `m` nicht in B implementieren, würde stattdessen (wegen der Vererbung) in beiden Fällen `mA` ausgegeben. +endif::solution[] + +### Frage +---- +for (Object o : objects) { + String s = (String) o; + System.out.println(s); +} +---- + +Ist das eine gute Idee? Warum? + +ifdef::solution[] +.Antwort +Das ist keine gute Idee, da man in den meisten Fällen einen spezifischeren Typ als `Object` verwenden kann und sollte. Außerdem ist der Downcast `(String) o` problematisch, da vorher nicht überprüft wurde ob es sich bei dem Inhalt der `Object`-Variable tatsächlich um einen `String` handelt. +endif::solution[] + +### Frage +---- +Object o = "abc"; +int l = (String) o.length(); +---- +Ooops, was ist da schiefgegangen? + +ifdef::solution[] +.Antwort +Der Cast-Operator bindet schwächer als der `.`. Dieser Code versucht die Methode `length` von `Object` aufzurufen und das Ergebnis zum Typ `String` zu casten. Das scheitert aber, da die Klasse `Object` keine Methode `length` hat. Richtig müsste es heißen `in l = ((String) o).length();` +endif::solution[] + +### Frage +Ein ...cast passiert implizit, wenn ein Objekt einer Variable von einem Supertyp zugewiesen wird. Ein ...cast muss dagegen explizit angegeben werden. + +ifdef::solution[] +.Antwort + +* Up- +* Down- +endif::solution[] + +### Frage +Was bedeutet das Wort "Polymorphie" von seiner sprachlichen Herkunft? + +ifdef::solution[] +.Antwort +Polymorphie bedeutet "Vielgestaltigkeit". Eine Variable vom Typ `List` ist z.B. vielgestaltig, weil das tatsächliche Objekt sowohl eine `ArrayList` als auch eine `LinkedList` sein könnte. +endif::solution[] + + +// Ab hier Kapitel 11.2 u. 11.4 + + +### Frage +Was gibt die Methode `toString` standardmäßig zurück? + +ifdef::solution[] +.Antwort +`Klassenname@hashCode` +endif::solution[] + +### Frage +Eine Klasse, die als `class A {}` deklariert wird, wird vom Compiler als `class A extends Object {}` aufgefasst. Wie ist das bei `class A extends B {}`? Ist eine Deklaration der Form `class A extends B, Object {}` oder `class A extends B extends Object {}` überhaupt erlaubt? + +ifdef::solution[] +.Antwort +Auch bei `A extends B {}` erbt `A` von Object. Allerdings geschieht das nicht direkt. Entweder hat `B` keine weitere Oberklasse und erbt damit von `Object`, oder die Vererbungskette geht noch einen oder mehrere Schritte weiter, bis die letzte Basisklasse erreicht ist, die dann von `Object` erbt. +endif::solution[] + +### Frage +Die Aussage ist nicht ganz korrekt: "`getClass` gibt die Klasse einer Instanz zurück." Berichtigen Sie den Satz. + +ifdef::solution[] +.Antwort +`getClass` gibt ein Instanz der Klasse `Class` zurück, die eine Beschreibung der Klasse enthält. +endif::solution[] + +### Frage +---- +class Foo { + int x; + public boolean equals(Object other) { + if (other instanceof Foo) { + Foo f = (Foo) other; + return f.x == x; + } + return false; + } +} +---- + +Diese Klasse hat laut der Spezifikation der Methode `equals` ein Problem. Welches ist das? + +ifdef::solution[] +.Antwort +Wenn `a.equals(b)` den Wert `true` ergibt, dann muss auch `a.hashCode() == b.hashCode()` gelten. Man müsste also noch die Methode `hashCode` überschreiben um diese Eigenschaft sicherzustellen. + +Außerdem gehört zum typischen Schema einer `equals`-implementierung noch am Anfang eine Überprüfung ob `other == this` gilt. In dem Fall kann man sofort `true` zurückgeben. + +Der Code funktioniert übrigens auch, wenn für `other` der Wert `null` übergeben wird, da `null instanceof X` immer `false` ergibt, egal welche Klasse man für `X` einsetzt. +endif::solution[] + +### Frage +Wie sieht schematisch die Syntax einer Schnittstellen-Deklaration aus? [vereinfachte Variante, so wie Schnittstellen meist verwendet werden] + +ifdef::solution[] +.Antwort +`interface Name { typ name(parameter); ... }` + +Die Benennung des Interfaces endet oft auf `-able`, um anzuzeigen, dass mit dem Interface irgendeine Fähigkeit bezeichnet wird. +endif::solution[] + +### Frage +Welche Methodenkörper wären für die Methode `hashCode` der Klasse `java.awt.Point` zulässig und sinnvoll? + +* `return x + y;` +* `return x;` +* `return y;` +* `return x ^ y;` +* `return (""+x+y).hashCode();` +* `return (x + "," + y).hashCode();` +* `return 0;` +* `return new Random().nextInt();` + +ifdef::solution[] +.Antwort +Der HashCode soll eine (möglichst) eindeutige Kennung eines Objektes darstellen. + +* `return x + y;` kann (1, 4) und (4, 1) nicht unterscheiden (weil `+` kommutativ ist). +* `return x;` ignoriert die Variable `y` und ist daher nicht sinnvoll. +* `return y;` ignoriert die Variable `y` und ist daher nicht sinnvoll. +* `return x ^ y;` kann (1, 4) und (4, 1) nicht unterscheiden (weil `^` kommutativ ist). +* `return (""+x+y).hashCode();` scheitert für (1, 14) und (11, 4). +* `return (x + "," + y).hashCode();` wäre eine sinnvolle Variante. +* `return 0;` gibt den gleichen HashCode für jedes Objekt. Das ist nicht sinnvoll. +* `return new Random().nextInt();` ist eindeutig, aber das selbe Objekt bekommt bei mehreren Aufrufen von HashCode unterschiedliche codes. Das ist weder zulässig noch sinnvoll. + +Zulässig sind prinzipiell alle HashCodes, bei denen sichergestellt ist dass gleiche Objekte (Vergleich mit `equals` ergibt `true`) auch den gleichen HashCode erhalten. Das ist bei allen dieser Beispiele bis auf `return new Random().nextInt();` der Fall. +endif::solution[] + +### Frage +Was ist richtig? + +[ ] `interface One extends Two` +[ ] `interface One implements Two` + +ifdef::solution[] +.Antwort +Die zweite Variante funktioniert nicht. + +Wenn man von mehreren Interfaces erben kann, kann man die folgende Syntax verwenden: +---- +interface A { void foo(); } +interface B { void bar(); } +interface C extends A, B { void baz(); } +---- +endif::solution[] + +### Frage +Man kann mit Überladung keine zwei Methoden mit gleicher _Signatur_ erstellen. Schließen Sie daraus, was der Begriff _Signatur_ bedeutet. + +ifdef::solution[] +.Antwort +Die Signatur ergibt sich aus dem Namen, dem Typ und der Anzahl der Parameter. +endif::solution[] + +### Frage +Eine Schnittstellendeklaration mit genau _einer_ abstrakten Methode heißen? + +ifdef::solution[] +.Antwort +Funktionale Schnittstelle +endif::solution[] + +### Frage +Wie können wir Java überprüfen lassen, ob eine Schnittstelle ein funktionales Interface ist? + +ifdef::solution[] +.Antwort +Mit der Annotation `@FunctionalInterface`. +endif::solution[] + +### Frage +Wie sieht schematisch die Syntax einer Methode in einer Schnittstelle aus, die mit einer Implementierung versehen ist? + +ifdef::solution[] +.Antwort +Die Methode muss das Schlüsselwort `default` haben. +endif::solution[] + +### Frage +Mit der Nutzung von `implements` im Kopf einer Klassendeklaration verpflichtet sich der Rumpf, was zu tun? + +ifdef::solution[] +.Antwort +Alle Methoden des Interfaces müssen implementiert werden. + +Ein Sonderfall wäre eine abstrakte Klasse. Hier kann die Implementierung von Methoden auch an Unterklassen delegiert werden. +endif::solution[] + +### Frage +Welchen Nutzen haben Schnittstellen außer von einer Klasse eine Implementierungsverpflichtung einzufordern? + +ifdef::solution[] +.Antwort +Man kann Schnittstellen als Typ im Code verwenden. +endif::solution[] + +### Frage +Karl sagt: "Wozu Schnittstellen, ich kann auch alles mit abstrakten Klassen machen, was Schnittstellen können." Was antwortet ihm Carla darauf? + +ifdef::solution[] +.Antwort +Man kann mehrere Schnittstellen implementieren, aber nur eine abstrakte Klasse erweitern. +endif::solution[] + +### Frage +Carla sagt: "Seitdem es default-Implementierungen bei Schnittstellen gibt, sind abstrakte Klassen überflüssig geworden." Was antwortet Karl darauf? + +ifdef::solution[] +.Antwort +Abstrakte Klassen können im Gegensatz zu Schnittstellen auch Felder besitzen. +endif::solution[] + +### Frage +---- +interface I { void foo(); } +class A implements I { void foo() {} } +---- +Autsch! Warum? + +ifdef::solution[] +.Antwort +Die Implementierung von `foo` müsste `public` sein, weil jede Methode eines Interfaces implizit `public` und `abstract` ist. +endif::solution[] + +### Frage +---- +abstract class A { void foo(); } +---- +Aua! Weshalb? + +ifdef::solution[] +.Antwort +`foo` muss als `abstract` definiert werden. +endif::solution[] + +### Frage +`interface I { abstract void foo(); }` Geht das? Macht das Sinn? + +ifdef::solution[] +.Antwort +Das geht, macht aber nicht viel Sinn, da `foo` sowieso `abstract` wäre, auch wenn man den Modifizierer nicht verwendet. +endif::solution[] + + + +### Frage +Die Frage ist angeregt durch den Code auf S.277 aus Kapitel 12. +---- +Geometrie geos = new Geometrie(); +---- +Ist `Geometrie` eine Klasse oder ein Interface? + +ifdef::solution[] +.Antwort +Das `new` und die runden Klammern für den argumentlosen Aufruf des Konstruktors verraten Ihnen, dass `Geometrie` eine Klasse sein muss. +endif::solution[] + +### Frage +Die Frage ist angeregt durch den Code auf S.277 aus Kapitel 12. +---- +Geometrie[] geos = new Geometrie[4]; +---- +Ist `Geometrie` eine Klasse oder ein Interface? + +ifdef::solution[] +.Antwort +Es wird hier ein Array mit Elementen vom Typ `Geometrie` angelegt, mehr nicht. Es bleibt nachwievor offen, ob der Typ eine Klasse oder ein Interface ist. +endif::solution[] diff --git a/Fragen/Kap.12.adoc b/Fragen/Kap.12.adoc new file mode 100644 index 0000000..748e26f --- /dev/null +++ b/Fragen/Kap.12.adoc @@ -0,0 +1,223 @@ +== Generische Klassen und Methoden + +.Die Syntax zu Typparametern +---- +TypeParameter: + {TypeParameterModifier} Identifier [TypeBound] + +TypeBound: + "extends" TypeVariable + "extends" ClassOrInterfaceType {AdditionalBound} + +AdditionalBound: + "&" InterfaceType +---- + +Eine Entscheidung: + +. Wir nehmen aus dem Kapitel 12 das Unterkapitel 12.4 (Wildcards) raus. +. Wir ignorieren ansonsten die Verwendung von `extends` bei der Angabe von Typparametern. + +Wir glauben, dass für Sie als Erstsemester einfache Generics genügen mögen. + +Notiz: +---- +jshell> class MyClass { N n = (N)(new Integer(8)); } +| Warning: +| unchecked cast +| required: N +| found: java.lang.Integer +| class MyClass { N n = (N)(new Integer(8)); } +| ^--------------^ +| modified class MyClass + +jshell> new MyClass().n +$16 ==> 8 + +jshell> new MyClass().n +$17 ==> 8 + +jshell> new MyClass().n +| java.lang.ClassCastException thrown: java.lang.Integer (in module: java.base) cannot be cast to java.lang.Long (in module: java.base) +| at (#18:1) +---- + +### Frage +Eine Klasse `Container` soll im Konstruktor einen beliebigen Typ als Inhalt (_content_) aufnehmen können. Schreiben Sie den Code ohne `Object` zu verwenden. + +ifdef::solution[] +.Antwort +[source,java] +---- +class Container { + T content; + Container(T content) { + this.content = content; + } +} +---- + +---- +jshell> new Container(3) +$20 ==> Container@17579e0f +---- +endif::solution[] + +### 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? + +ifdef::solution[] +.Antwort +[source,java] +---- +class Tupel { + T car; // das ist ein historischer Name + U cdr; // das ist ein historischer Name + Tupel(T first, U second) { + car = first; + cdr = second; + } +} +---- +endif::solution[] + +### Frage +Legen Sie eine neue `ArrayList` an, die ausschließlich aus Ganzzahlen besteht. + +ifdef::solution[] +.Antwort +---- +new ArrayList(); +---- +endif::solution[] + +### Frage +Was ist ein _Typparameter_? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Deklarieren und initialisieren Sie eine Variable `a`, die ausschließlich eine `ArrayListe` von boolschen Werten aufnehmen kann. Die Lösung muss so kurz wie möglich sein. + +ifdef::solution[] +.Antwort +Entweder Sie deklarieren `a` vom Typ `ArrayList`: + +---- +ArrayList a = new ArrayList<>(); +---- + +Oder, was Sie oft sehen, Sie nehmen das `List`-Interface als Typ, der durch die `ArrayList` implementiert wird. + +---- +List a = new ArrayList<>(); +---- +endif::solution[] + +### Frage +Wie lautet die Syntax für eine generische Methode? + +ifdef::solution[] +.Antwort +---- + Rückgabetyp methodName(parameters) { ... } +---- +endif::solution[] + +### Frage +Inwiefern hebelt die Definition ` T giveMeWhatIWant() { ... }` das Typsystem von Java aus? + +ifdef::solution[] +.Antwort +Diese Methode muss eine Implementierung bieten, die für jeden Typ passen muss. +// S. 269: Es kommt darauf an, was eine Instanz kann, nicht wie sie aussieht +endif::solution[] + + +### Frage +Wie sieht schematisch die Syntax einer generischen Klasse aus? Reduzieren Sie die Syntax auf das Notwendigste. + +ifdef::solution[] +.Antwort +---- +class Name { ... } +---- +endif::solution[] + +### Frage +---- +class A { void foo(T x) {} } +A myA = new A(); +---- +Kann man das schreiben? Welcher Typ wird für den Typparameter `T` eingesetzt? + +ifdef::solution[] +.Antwort +Der allgemeinste Typ hier, der implizit eingesetzt wird, ist `Object`. Aber: Das ist kein guter Programmierstil. +endif::solution[] + +### Frage +---- +class Foo { + int getLength(T value) { + return value.length(); + } +} +Foo f = new Foo<>(); +f.getLength("abc"); +---- +Oh Schmerz! Weswegen? + +ifdef::solution[] +.Antwort +Man kann nicht davon ausgehen, dass `value`, dessen Typ über `T` frei gewählt werden kann, eine `length`-Method hat. +endif::solution[] + +### Frage +`class Bar { Blubber x; }` Problem? + +ifdef::solution[] +.Antwort +Nein, kein Problem. Es ist unüblich, lange Namen für Typparameter zu wählen. Per Konvention verwendet man nur einzelne Großbuchstaben. +endif::solution[] + + + +### Frage +Man kann eine Klasse als `MyClass` deklarieren, ist auch `MyClass` erlaubt? + +ifdef::solution[] +.Antwort +Das `implements` ist in der Syntax nicht vorgesehen, ist nicht erlaubt. +endif::solution[] + +### Frage +`class ICanHazGenerics {}` Und schon gibt's was auf die Finger. Was ist der Grund? + +ifdef::solution[] +.Antwort +Man sollte den Typ für `Comparable` angeben. +endif::solution[] + +### Frage +`class A {}` Kann man `A value = new A();` schreiben? Gilt also `B extends B`? + +ifdef::solution[] +.Antwort +Die Klasse `B` als `T` kann das, was `B` kann, das meint ``. +endif::solution[] + +### Frage +---- +List lst = new ArrayList<>(); +lst.add(new Integer(8)); +---- +Die zweite Zeile produziert einen Fehler. Können Sie sich vorstellen, warum man einer `List` keinen `Integer` hinzufügen kann? + +ifdef::solution[] +.Antwort +Man könnte mal einen `Integer` der Liste hinzufügen, mal einen `Double`. Der Compiler kann diese Entscheidung nicht auflösen. +endif::solution[] diff --git a/Fragen/Kap.14.adoc b/Fragen/Kap.14.adoc new file mode 100644 index 0000000..26fc3da --- /dev/null +++ b/Fragen/Kap.14.adoc @@ -0,0 +1,423 @@ +== Collections + +[TIP] +==== +Hinweis: Die `forEach`-Methode erwartet einen Lambda-Ausdruck. Das kommt noch. +==== + +### Frage +Welche besondere Bedeutung hat das Interface `Iterable` in Java? + +ifdef::solution[] +.Antwort +Wenn eine Klasse `Iterable` implementiert, kann man sie in einer for-each-Schleife verwenden. +endif::solution[] + +### Frage +Sie wollen `ArrayList` verwenden und dürfen nicht vergessen, welches Paket zu importieren? + +ifdef::solution[] +.Antwort +`java.util` +endif::solution[] + +### Frage +Welche dieser Klassen implementiert das Interface `Collection`? + +[ ] HashSet +[ ] LinkedList +[ ] Stack +[ ] TreeMap + +ifdef::solution[] +.Antwort +`TreeMap` ist die einzige Klasse aus der Liste, die keine `Collection` ist (obwohl sie zum _Collection Framework_ gehört). +endif::solution[] + +### Frage +Auf S.295 oben heißt es: "... bietet sich der Einsatz einer `List`-Klasse an." Ist `List` eine Klasse? + +ifdef::solution[] +.Antwort +Nein, `List` ist ein Interface. +endif::solution[] + +### Frage +---- +Set s = new HashSet(); +for(int i = 0; i < 100; i++) { + int x = new Random().nextInt(); + if (! s.contains(x)) s.add(x); +} +---- + +ifdef::solution[] +.Antwort +Das `if (! s.contains(x))` kann man sich sparen, da ein `Set` sowieso jedes Element nur einmal enthalten kann. + +---- +Set s = new HashSet(); +for(int i = 0; i < 100; i++) { + s.add(new Random().nextInt()); +} +---- +endif::solution[] + +### Frage +Was bedeutet _First in - First out_? + +ifdef::solution[] +.Antwort +Das Element, das zuerst hinzugefügt wurde wird als erstes wieder aus der Datenstruktur entfernt. Das ist z.B. bei einer Queue der fall. +endif::solution[] + +### Frage +Warum gibt es für eine Schnittstelle wie z.B. `List` mehrere Implementierungen wie z.B. `ArrayList` oder `Stack`? Woher soll ich wissen, welche Implementierung ich nutzen soll? + +ifdef::solution[] +.Antwort +Die Implementierungen haben verschiedene Laufzeiten für die Ausführung der einzelnen Methoden. Man kann damit also abhängig davon welche Methoden man am häufigsten braucht entscheiden welche Implementierung besser für das eigene Problem funktioniert. +endif::solution[] + +### Frage +Den Interfaces `Set`, `List`, `Stack`, `Queue` und `Map` liegen anschauliche Vorstellungen zugrunde. Zeichnen Sie für jedes Interface ein Bild, was die zugrunde liegende Abstraktion illustriert. [Das soll helfen, sich zu erinnern, was die Schnittstellen tun.] + +ifdef::solution[] +.Antwort + +* Set (Menge): Korb oder Kreis mit ungeordneten Elementen +* List (Liste): Regenwurm mit aneinanderhängenden Segmenten +* Stack (Stapel): Gefäß, in das man nur von oben Sachen hineinlegen oder entfernen kann (LIFO) +* Queue (Puffer): Warteschlange, Einbahnstraße (FIFO) +* Map (Abbildung): Telefonbuch, Wörterbuch + +image::images/CollectionBilder.jpg[] +endif::solution[] + +### Frage +Warum kann man bei einer `Collection` die Variante der `for`-Schleife nutzen, die sich foreach-Schleife nennt? + +ifdef::solution[] +.Antwort +Weil `Collection` das Interface `Iterable` erweitert. +endif::solution[] + +### Frage +Warum sollten Sie davon Abstand nehmen, `Collection`s selber zu implementieren? + +ifdef::solution[] +.Antwort +Weil die bestehenden Implementierungen sehr effizient und ausgeklügelt sind. +endif::solution[] + +### Frage +Warum ist es oft attraktiv, wenn möglich, eine Schnittstelle statt eine Klasse als Typ einer Variablen anzugeben? + +ifdef::solution[] +.Antwort +Wenn man eine Schnittstelle verwendet, erhöht man die Wiederverwendbarkeit des Codes und man hat die Möglichkeit, später noch die konkrete Implementierung zu wechseln. +endif::solution[] + +### Frage +Warum ist es bei Collections manchmal sinnvoller, eine Variable mit der implementierenden Klasse statt dem Interface zu deklarieren. + +ifdef::solution[] +.Antwort +Manchmal möchte man Methoden einer Klasse verwenden, die nicht im Interface angegeben sind. Außerdem gibt es Fälle in denen eben nur eine konkrete Implementierung sinn macht (z.B. der `Stack` beim UPN-Taschenrechner). +endif::solution[] + +### Frage +---- +List lst = ...; +for(int i = 0; i < lst.size(); i++) { + if (lst.get(i) < 0) lst.remove(i); +} +---- +Ojemine! Aus welchem Grunde? + +ifdef::solution[] +.Antwort +Diese Implementierung überspringt elemente in der Liste. Besser ist es hier einen `Iterator` zu verwenden. +endif::solution[] + +### Frage +Herr Kofler benennt fünf statische Methoden der Klasse `Collections`, die nützlich sind -- und oft gebraucht werden. + +ifdef::solution[] +.Antwort + +* `min` +* `max` +* `fill` +* `binarySearch` +* `sort` +endif::solution[] + +### Frage +Dem Kopf der `for`-Schleife fehlt doch was, oder? + +`for(Iterator it = s.iterator(); it.hasNext(); )` + +Kann so eine `for`-Schleife überhaupt funktionieren? + +ifdef::solution[] +.Antwort +Der Kopf besitzt keine Schrittanweisung. So eine Schleife kann man durchaus definieren. Dann muss man aber die Schrittanweisung selbst im Körper der Schleife realisieren (in diesem Beispiel durch den Aufruf von `it.next()`). + +In so einem Fall ist eigentlich eine `while`-Schleife sinnvoller. +endif::solution[] + +### Frage +Listen Sie freisprachlich auf (jeweils ein Verb), welche Fähigkeiten eine `Collection` mit sich bringt. + +ifdef::solution[] +.Antwort + +* Größe ermitteln +* Elemente hinzufügen +* Elemente entfernen +* Prüfen ob ein Element in der `Collection` enthalten ist +endif::solution[] + +### Frage +Was ist der wesentliche Unterschied zwischen einer Liste (`List`) und einer Menge (`Set`)? + +ifdef::solution[] +.Antwort +Eine Liste kann mehrere gleiche Elemente enthalten. Außerdem hat sie eine definierte Ordnung. +endif::solution[] + +### Frage +`Set` definiert `add` mit dem Rückgabetyp `boolean`. Warum? + +ifdef::solution[] +.Antwort +Wenn das Element schon enthalten ist, fügt `add` das Element nicht hinzu. Um diesen Fall zu erkennen, wird `false` zurückgegeben und `true` sonst. +endif::solution[] + +### Frage +In welcher Klasse finden Sie eine Methode um Listen zu sortieren? + +ifdef::solution[] +.Antwort +`java.util.Collections` +endif::solution[] + +### Frage +Die Implementierung `HashSet` erwartet, das der parametrisierte Typ zwei Methoden "sauber" implementiert hat? Welche sind das? + +ifdef::solution[] +.Antwort +`equals` und `hashSet` +endif::solution[] + +### Frage +Der Unterschied zwischen einem `LinkedHashSet` und einem `HashSet` ist? + +ifdef::solution[] +.Antwort +Das `LinkedHashSet` erhält die chronologische Reihenfolge. +endif::solution[] + +### Frage +Was ist ein `TreeSet`? + +ifdef::solution[] +.Antwort +Ein `TreeSet` sortiert seine Element intern. +endif::solution[] + +### Frage +`Set pset = new TreeSet();` Schon verloren. Wie kommt's? + +ifdef::solution[] +.Antwort +`java.awt.Point` implementiert das Interface `Comparable` nicht, das aber nötig ist damit `TreeSet` seine Elemente sortieren kann. Man müsste dem Konstruktor einen `Comparator` übergeben, um das Problem zu lösen. +endif::solution[] + +### Frage +Welchen Wert hat `new ArrayList(10).size()`? + +ifdef::solution[] +.Antwort +`0` +endif::solution[] + +### Frage +Wann sollte man der `LinkedList` den Vorrang vor `ArrayList` geben? + +ifdef::solution[] +.Antwort +Wenn man sehr häufig Elemente an beliebiger Stelle einfügen oder löschen möchte. +endif::solution[] + +### Frage +Was heißt "FIFO", was "LIFO"? (Das sind zwei ganz beliebte Abkürzungen.) + +ifdef::solution[] +.Antwort + +* FIFO = _First in - First out_ +* LIFO = _Last in - First out_ +endif::solution[] + +### Frage +Wie sollte man am Besten eine Liste oder ein Set kopieren? + +ifdef::solution[] +.Antwort +Mit einem _Copy-Konstruktor_ (d.h. ein Konstruktor, der eine `Collection` übernimmt und alle Elemente aus dieser Collection dem neu erstellten Objekt hinzufügt). +endif::solution[] + +// Ab hier geht es um Maps (14.7) + +### Frage +Wenn Sie über Schlüssel-Wert-Paare einer Map iterieren wollen (und beides brauchen), können Sie die Methode `entrySet` verwenden. Der Rückgabetyp dieser Methode ist `Set>`. Erklären Sie diesen Typ. + +ifdef::solution[] +.Antwort +Der Rückgabetyp ist ein `Set`, dessen Elemente den Typ `Map.Entry` haben. `Map.Entry` ist ein _inneres Interface_ des Interface `Map`. Das ist das gleiche Prinzip wie bei einer inneren Klasse. `Map.Entry` ist außerdem generisch, damit man den Typ des Schlüssels `K` und den Typ des Werts `V` angeben kann. +endif::solution[] + +### Frage +Ist `Map.Entry` als `static` deklariert oder nicht? Woran sieht man das? + +ifdef::solution[] +.Antwort +Da `Entry` ein Interface ist, macht es gar keinen Unterschied, ob es `static` ist oder nicht. Tatsächlich wird das Schlüsselwort `static` sogar implizit ergänzt. Das kann man auch sehen an dem Fehler, den der Compiler bei folgendem Konstrukt angibt: + +---- +class A { + int x; + interface B { + default void foo() { + System.out.println(x); + } + } +} +---- +endif::solution[] + +### Frage +Die `Map`-Schnittstelle gehört nicht zu den Collections. Was könnte der Grund dafür sein? + +ifdef::solution[] +.Antwort +Im Gegensatz zu einer normalen `Collection` handelt es sich bei den Elementen einer Map nicht um einzelne Werte, sondern um Schlüssel-Wert-Paare. Wenn `Map` das Interface `Collection` und damit auch `Iterable` implementieren würde, müsste man sich für eine Sicht bei der Iteration entscheiden: Nur Schlüssel, nur Werte oder Schlüssel-Wert-Paare. Die Java-Entwickler haben diese Entscheidung dem Benutzer überlassen mit den Methoden `keySet`, `values` und `entrySet`. +endif::solution[] + +### Frage +Die `Map`-Schnittstelle hat zwei wichtige Methoden `put` und `get`. Was vermuten Sie, wie die Methodenköpfe zu den beiden Methoden aussehen? + +ifdef::solution[] +.Antwort +Vermuten würde man das folgende: + +---- +void put(K key, V value); +V get(K key); +---- + +Die tatsächlichen Methodenköpfe sehen aber wie folgt aus: + +---- +V put(K key, V value); +V get(Object key); +---- + +`put` gibt tatsächlich den alten Wert zurück, der unter dem Schlüssel gespeichert war oder `null` falls der Schlüssel noch nicht existierte. + +`get` übernimmt seltsamerweise ein `Object`. Vermutlich ist das der Fall, da `get` über die `equals`-Methode definiert ist, die ebenfalls ein beliebiges `Object` akzeptiert. Eine sauberere Deklaration im Sinne der Typsicherheit wäre aber tatsächlich `V get(K key);` gewesen. + +Tatsächlich gibt die Java-API den Grund an, dass man auch ein Objekt eines anderen Typs als des Schlüsseltyps verwenden kann um Elemente aus der Map zu identifizieren. Es muss nur gegeben sein, dass `key.equals(k)` für den zu findendenden Schlüssel `k` in der Map `true` ergibt. Eine sinnvolle Anwendung dieser Eigenschaft wäre z.B. wenn man ein Interface `Point` mit den Implementierungen `CarthesianPoint` und `PolarPoint` hat. In diesem Fall könnte ein `CarthesianPoint` mit `equals` mit einem `CarthesianPoint` vergleichbar sein. Dann könnte man eine Map vom Typ `Map` definieren, bei der man aber auch `PolarPoint` Objekte verwenden kann, um auf die in der Map enthaltenen Werte zugreifen kann. + +//// +Codebeispiel: (TODO) +---- +class Rad { + float rad; + public boolean equals(Object other) { + if(other instanceof Rad) { + return Math.abs(rad - ((Rad)other).rad) < 0.0001; + } else if (other instanceof Deg) { + return ((Deg) other).toRad().equals(this); + } + } +} + +class Deg { + float deg; + public boolean equals(Object other) { + + } +} +---- +//// +endif::solution[] + +### Frage +---- +class A { int x; A(int x) {this.x = x; } } +Map myMap = new HashMap<>(); +myMap.put(new A(1), 1); +myMap.put(new A(1), 2); +---- + +Was ergibt `myMap.size()`? + +ifdef::solution[] +.Antwort +Das Ergebnis ist `2`, da die Klasse `A` keine `equals`-Methode implementiert und damit die `equals`-Implementierung von `Object` verwendet. Die Implementierung von `equals` alleine reicht hier übrigens nicht aus, da eine `HashMap` überhaupt erst `equals` aufruft, wenn beide Objekte schon den gleichen `hashCode` haben. Genau genommen müssen Sie also für dieses Beispiel `hashCode` _und_ `equals` überschreiben. + +Der Code hat auch noch ein ganz anderes Problem, denn man kann nicht mehr auf die Schlüssel zugreifen, die in der Map gespeichert wurde, da man keine Referenz mehr auf den Schlüssel hat. +endif::solution[] + +### Frage +Zur `Map`-Schnittstelle finden Sie `boolean containsKey(Object key)` deklariert. Komisch? Komisch! Was ist an der Deklaration überraschend? + +ifdef::solution[] +.Antwort +Ähnlich wie bei `get` ist der Parameter von `containsKey` vom Typ `Object` statt vom Schlüsseltyp `K`. (Siehe dazu die Diskussion der Frage zu Deklaration von `get`.) +endif::solution[] + +### Frage +Was unterscheidet eine `HashMap` von einer `LinkedHashMap`? Welche der beiden Implementierungen verwenden Sie im Regelfall? + +ifdef::solution[] +.Antwort +`LinkedHashMap` bietet eine Ordnung der Schlüssel-Wert-Paare, die man aber in den meisten Fällen nicht braucht. Daher verwendet man im Regelfall `HashMap`. +endif::solution[] + +### Frage +Welche Probleme ergeben sich, wenn die Schlüssel einer Map veränderliche Objekte sind? + +ifdef::solution[] +.Antwort +Das Verhalten der Map wird dadurch undefiniert. Es könnten sogar zwei Schlüssel in der Map existieren, bei denen der Vergleich mit `equals` den Wert `true` ergibt. +endif::solution[] + +### Frage +Wenn man über den Inhalt einer Map iterieren möchte gibt es drei Möglichkeiten an ein Objekt zu gelangen das `Iterable` implementiert. Diese Möglichkeiten entsprechen jeweils einer anderen Sicht auf den Inhalt der Map. Welche sind das? + +ifdef::solution[] +.Antwort +Alle Schlüssel mit `keySet`, alle Werte mit `values` oder alle Schlüssel-Wert-Paare mit `entrySet`; +endif::solution[] + +### Frage +Die Map-Methode `put` liefert einen Wert zurück. Weshalb ist Sie nicht einfach als `void` deklariert? + +ifdef::solution[] +.Antwort +Die Methode gibt den alten Wert zurück, der unter dem gegebenen Schlüssel gespeichert war (oder `null` falls der Key noch nicht existierte). +endif::solution[] + +### Frage +Angenommen, Sie haben eine `Map` namens `book` vom Typ `HashMap`. Schreiben Sie den Kopf einer `for`-Schleife, die über alle ISBNs iteriert. + +ifdef::solution[] +.Antwort +---- +for(ISBN isbn: book.keySet()) +---- +endif::solution[] diff --git a/Fragen/Kap.15.adoc b/Fragen/Kap.15.adoc new file mode 100644 index 0000000..7f7b66d --- /dev/null +++ b/Fragen/Kap.15.adoc @@ -0,0 +1,242 @@ +== Dateien und Verzeichnisse + +Tabelle 15.2, 15.3, 15.4 sind wieder ein Gold-Nuggets. + +### Frage +Handelt es sich bei `java.io.IOException` um eine _geprüfte_ oder eine _ungeprüfte_ Ausnahme? Weshalb? + +ifdef::solution[] +.Antwort +Etwas, was keine Runtime-Exception ("dumme Programmierfehler") und kein Error (schwerwiegender Fehler) ist. Checked Exceptions (geprüfte Ausnahmen) müssen gefangen werden oder explizit weitergereicht werden. + +Eine `IOException` ist eine Ausnahme, deren Auftreten ausserhalb meiner Verantwortung liegt, deshalb auftreten kann und unbedingt behandelt werden muss. +endif::solution[] + +### Frage +Welches Konstrukt sollte man verwenden, um Ressourcen nach der Verwendung automatisch zu schließen? + +ifdef::solution[] +.Antwort +_try-with-resource_, `try (...) catch/finally`. +endif::solution[] + +### Frage +Geben Sie zwei Beispiele an, warum die Arbeit mit dem Dateisystem zu Exceptions führen kann. + +ifdef::solution[] +.Antwort +Zum Beispiel: + +* Die Datei existiert nicht +* Die Datei ist schreibgeschützt und kann nicht überschrieben werden +endif::solution[] + +### Frage +[source,java] +---- +try (BufferedReader br = Files.newBufferedReader("test.txt", StandardCharsets.UTF_8)) { + // ... +} +---- +Könnte ich nicht nach diesem Block noch einmal `br.readLine()` aufrufen wollen? Weshalb kann `br` direkt nach Ende der geschweiften Klammer geschlossen werden? + +ifdef::solution[] +.Antwort +Innerhalb des `try`-Blocks wird die Ressource angelegt und dann wieder geschlossen. +endif::solution[] + +### Frage +Welches gedankliche Modell liegt einer Ressource zugrunde, so dass man die Arbeit mit ihr per `close`-Methode abschliesst? (edited) + +ifdef::solution[] +.Antwort +In der Java-Welt haben Sie nur ein Abbild von Geräten, "Dingen" etc., die sich außerhalb der JVM befinden, wie die vom Betriebssystem Ihres Rechners verwalteten Dateien, Ausgabegeräte, Eingabegeräte usw. Dieses Abbild gleicht Java in entsprechenden Klasseninstanzen ab. Die Synchronisationspunkte gibt es nur gelegentlich mit dem Aufruf mancher Methoden. Mit `close()` wird die Verbindung zur Außenwelt aufgelöst, es findet kein Austausch oder Abgleich mit der vormals assoziierten Ressource mehr statt. +endif::solution[] + +### Frage +Wofür brauchen Sie die Methode `System.getProperty`? Nennen Sie Beispiele für Eigenschaften, die Sie mit dieser Methode auslesen können. + +ifdef::solution[] +.Antwort +Zum Beispiel `user.dir`, `user.home`. +endif::solution[] + +### Frage +Was liefert in der JShell `jshell> System.getProperty("user.dir")` zurück? + +ifdef::solution[] +.Antwort +Es ist das Verzeichnis, in dem die JShell gestartet wurde. +endif::solution[] + +### Frage +Sie bekommen einen geheimen Pfad `geheim` vom Typ `Path`. Prüfen Sie, ob es sich dabei um ein existierendes Verzeichnis handelt und erstellen Sie dann ein neues `Path`-Objekt, das auf die Datei `test.jar` im Unterverzeichnis `lib` dieses Verzeichnisses verweist. + +ifdef::solution[] +.Antwort +---- +Path geheim = ... ; +if(File.exists(geheim) && Files.isDirectory(geheim)) { /* ... */ } +---- +kann man verkürzen auf +---- +if(File.isDirectory(geheim)) { /* ... */ } +---- + +---- +Path p = geheim.resolve("lib").resolve("test.jar"); +---- +---- +Path p2 = geheim.resolve("lib/test.jar"); +---- +Der Separator `/` ist Linux-Schreibweise. Die Klasse `Path` ist "clever" implementiert und kann das jedoch unabhängig vom verwendeten Betriebssystem verstehen. +endif::solution[] + +### Frage +Was ist ein _absoluter_ Pfad? + +ifdef::solution[] +.Antwort +Unter Windows beginnt der Pfad mit dem Laufwerksbuchstaben. Unter Linux beginnt er mit dem Slash `/`. +endif::solution[] + +### Frage +Unter Windows entspricht `System.getProperty("user.dir")` welcher Umgebungsvariablen (aubrufbar in der Kommandozeile)? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Mit welchem Kommando in der Windows-Kommandozeile wechseln Sie das Verzeichnis? Wir schauen Sie sich den Inhalt eines Verzeichnisses an? + +ifdef::solution[] +.Antwort +* `cd` für _change directory_ unter Windows und Linux +* `dir` für _directory_, `ls` für _list_ unter Linux +endif::solution[] + +### Frage +Sie haben wieder einen geheimen Pfad `geheim`, der auf eine Datei `MyTest.java` verweist. Sie wissen nicht, in welchem Verzeichnis sich die Datei befindet, aber sie wissen dass es dort auch eine Datei namens `MyOtherTest.java` gibt. Nennen Sie zwei Wege, wie sie einen Pfad zu dieser Datei erzeugen können. + +ifdef::solution[] +.Antwort +-- TODO -- +// eine einzige `resolve`-Zeile +// ../ -- damit wechselt man relativ e +endif::solution[] + +### Frage +Was ist eine Datei? + +ifdef::solution[] +.Antwort +Auf einer Festplatte eine verteilte Ablage von Nullen und Einsen zusammen, die das Betriebssystem als logische Einheit organisiert. In Java findet sich davon dann eine objektorientierte Abbildung. +endif::solution[] + +### Frage +Was ist ein Verzeichnis? + +ifdef::solution[] +.Antwort +Eine logische Organisationstruktor für Dateien und teils (so unter Linux) von Ressourcen. In Java bekommen wir nur objektorientierte Abbildungen davon zu sehen. +endif::solution[] + +### Frage +Wie muss die Signatur der Methode `Paths.get` aussehen, wenn Sie beliebig viele Strings als Argumente akzeptiert? + +ifdef::solution[] +.Antwort +Das ist der Varargs-Parameter. + +Wie kann `Paths.get` eigentlich erzwingen, dass mindestens ein Argument übergeben werden _muss_? Der erste Parameter ist "normal", der zweite ein Varargs-Parameter. + +---- +Path get(String first, String... more) +---- +endif::solution[] + +### Frage +Was ist ein Link? + +ifdef::solution[] +.Antwort +Gemeint ist der Verweis auf ein anderes Verzeichnis oder eine andere Datei, +endif::solution[] + +### Frage +Wie kopiert und wie verschiebt man eine Datei unter Windows von der Konsole aus? + +ifdef::solution[] +.Antwort +* `copy` unter Windows, `cp` unter Linux/Powershell +* `move` unter Windows, `mv` unter Linux/Powershell +endif::solution[] + +### Frage +Welche Methode der Klasse `Files` liefert einen `Stream` - `newDirectoryStream` oder `list`? + +ifdef::solution[] +.Antwort +`list` ist ein Stream, `newDirectoryStream` eben nicht. +endif::solution[] + +### Frage +Schreiben Sie ein Programmfragment, das eine Textdatei zeilenweise einliest. + +ifdef::solution[] +.Antwort +Im nachfolgenden Code ist `inFileName` vom Typ `String`. +[source,java] +---- +BufferedReader inFile = new BufferedReader(new FileReader(inFileName)); +while((line = inFile.readLine()) != null) { + // ... +} +inFile.close(); +---- +Diese Kurzlösung gibt kein Kodierungsformat für die einzulesende Textdatei an. Das kann in manchen Fällen wichtig und notwendig sein. +endif::solution[] + +### Frage +Schreiben Sie ein Programmfragment, das die Einträge eines String-Arrays als einzelne Zeilen in eine Textdatei schreibt. + +ifdef::solution[] +.Antwort +Im nachfolgenden Code ist `outFileName` vom Typ `String` und `lines` vom Typ `String[]`. + +[source,java] +---- +BufferedWriter outFile = new BufferedWriter(new FileWriter(outFile1Name)); +for(String line : lines) { + outFile.write(line); + outFile.newLine(); +} +outFile.close(); +---- +endif::solution[] + +### Frage +Muss man immer `Files.createFile` zum Anlegen einer neuen Datei verwenden, oder geht das auch einfacher? + +ifdef::solution[] +.Antwort +Wenn man eine Datei zum Schreiben öffnet, wird sie angelegt, wenn sie nicht existiert. +endif::solution[] + +### Frage +Was bedeuten die Zahlen in `UTF-8`, `UTF-16` und `UTF-32` + +ifdef::solution[] +.Antwort +Die Zahlen geben an, mit wievielen Bits das Unicode-Zeichen per default kodiert ist. Aber: ein `UTF-8` (ein Byte) oder `UTF-16` (zwei Bytes) bezieht gegebenenfalls nachfolgende Bytes ein, um andere `UTF-32`-Zeichen darzustellen. +endif::solution[] + +### Frage +Muss man immer `Files.createDirectory` bzw. `Files.createDirectories` aufrufen um ein neues Verzeichnis zu erstellen, oder geht das auch einfacher? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] diff --git a/Fragen/Kap.18.adoc b/Fragen/Kap.18.adoc new file mode 100644 index 0000000..26feb2b --- /dev/null +++ b/Fragen/Kap.18.adoc @@ -0,0 +1,178 @@ +== Pakete und Bibliotheken + +### Frage +Ist es möglich, umfangreiche Java-Programme ohne eine einzige `import`-Anweisung zu schreiben? + +ifdef::solution[] +.Antwort +Ja, Imports sind immer optional, da man auch den _voll qualifizierten Namen_ von Referenztypen verwenden kann. +endif::solution[] + +### Frage +---- +import java.util.Arrays.sort; +int[] a = {4,1,3}; +sort(a); +---- +Fügen Sie ein Schlüsselwort an der richtigen Stelle ein, damit der Code funktioniert. + +### Frage +Eine `import`-Anweisung muss immer wo stehen? + +ifdef::solution[] +.Antwort +Ganz am Anfang der Quellcodedatei (aber unter der `package`-Deklaration). +endif::solution[] + +### Frage +In den Fragen zu vorherigen Kapiteln haben wir immer `java.awt.Point` als Typ verwendet statt `Point`. Weshalb haben wir das gemacht und was muss man tun, um einfach direkt `Point` schreiben zu können? + +ifdef::solution[] +.Antwort +Wir haben `java.awt.Point` nicht importiert (um eine Zeile zu sparen), deshalb mussten wir den _voll qualifizierten Klassennamen_ angeben. Wenn man den import `import java.awt.Point;` schreibt, kann man danach auch einfach `Point` schreiben. +endif::solution[] + +### Frage +Was kann man mit `import` importieren? + +ifdef::solution[] +.Antwort +Klassen, Interfaces, Enums +endif::solution[] + +### Frage +Was kann man mit `import static` importieren? + +ifdef::solution[] +.Antwort +Methoden, Felder und die Werte von Enums +endif::solution[] + +### Frage +Warum ist `import` ein irreführender Name? Tatsächlich organisiert man über `import` nur ___räume! + +ifdef::solution[] +.Antwort +Es geht um _Namensräume_. +endif::solution[] + +### Frage +---- +import java.awt.Point; +class Point { int x,y,z; } +Point p = new Point(); +---- +Problem? + +ifdef::solution[] +.Antwort +`Point` ist an dieser Stelle mehrdeutig, da es eine lokale Klasse und eine importierte Klasse gibt. +endif::solution[] + +### Frage +---- +import java.awt.*; +Point p; +---- +Geht das gut? + +ifdef::solution[] +.Antwort +Ja, da `Point` in dem Paket `java.awt` definiert ist und der `*` alle Klassen (und Interfaces und Enums) in dem Paket importiert. + +Hinweis: Der `*` importiert *keine* Klassen die in Unterpaketen des angegebenen Pakets liegen, also z.B. in `java.awt.color`. +endif::solution[] + +### Frage +Was ist der Unterschied von `import de.thm.mni;` und `import de.thm.mni.*;`? + +ifdef::solution[] +.Antwort +Im ersten Fall soll eine Klasse namens `mni` aus dem Paket `de.thm` importiert werden, der zweite Ausdruck importiert alle Klassen in `de.thm.mni`. +endif::solution[] + +### Frage +Welches Paket ist standardmäßig in Java SE importiert? + +ifdef::solution[] +.Antwort +`java.lang` +endif::solution[] + +### Frage +`import static java.awt.Color.*` Jetzt darf ich `Color c = new Color(0,0,0);` deklarieren, richtig? + +ifdef::solution[] +.Antwort +Nein, weil der Import nur alle öffentlichen Member der Klasse `Color` importiert, nicht aber die Klasse selbst. +endif::solution[] + +### Frage +Wozu braucht man auf S.372 oben am Anfang die Codezeile `import java.awt.Color;` wenn unten darunter `import static java.awt.Color.*;` steht? + +ifdef::solution[] +.Antwort +Der erste `import` importiert die Klasse `Color`. Der zweite `import` ist `static` und importiert die statischen Members von `Color`. +endif::solution[] + +### Frage +Was muss man tun, damit man die Methoden der Klasse `Math` direkt ohne den Anteil `Math.` in seinem Code verwenden kann? + +ifdef::solution[] +.Antwort +`import static java.lang.Math.*;` +endif::solution[] + +### Frage +Kann ich die Klasse `java.awt.Color` und eine Klasse `de.thm.mni.Color` zusammen im gleichen Stück Code verwenden? + +ifdef::solution[] +.Antwort +Ja, man darf aber nur eine dieser Klassen importieren. Die andere muss man über den _voll qualifizierten Namen_ ansprechen. +endif::solution[] + +### Frage +Man kann `import static java.lang.System.out;` schreiben. Dann geht doch auch `import static java.lang.System.out.println;`, oder? + +ifdef::solution[] +.Antwort +Nein, das geht nicht, weil `out` ein Objekt ist. Man kann keine Methoden aus einem Objekt importieren. +endif::solution[] + +### Frage +Was ist der Unterschied von `import de.thm.mni.OOP;` zu `import static de.thm.mni.OOP;` + +ifdef::solution[] +.Antwort +Der erste import importiert die Klasse `OOP` aus dem Paket `de.thm.mni`. Der zweite importiert etwas mit Namen `OOP` aus der Klasse `mni` im Paket `de.thm`. +endif::solution[] + +### Frage +Sie schreiben ein Programm im Fachbereich MNI der THM im Kurs OOP. Sie definieren ein Paket für Ihr Programm. Wie sollte der Paketname anfangen? + +ifdef::solution[] +.Antwort +`de.thm.mni.oop` +endif::solution[] + +### Frage +Die Option `-cp` bei `java` bzw. `javac` steht für welches Java-Konzept? + +ifdef::solution[] +.Antwort +Diese Option steht für den _Classpath_, in dem die JVM nach `.class`-Files sucht. +endif::solution[] + +### Frage +Welche Argumente müssen sie an `java` übergeben, wenn sie eine eigene Klasse `main.Main` ausführen wollen, die das Paket `somePackage.jar` verwendet? In welchen Ordnern sucht die JVM dabei nach der `.class`-Datei von `main.Main` und der Datei `somePackage.jar`? + +ifdef::solution[] +.Antwort +`java -cp somePackage.jar:. main.Main` + +Die JVM sucht nach `main.Main` sowohl als `./main/Main.class` als auch als `somePackage.jar!main/Main.class` (das `!` steht dafür, dass das JAR-Archiv geöffnet und betreten wird). Die Datei `somePackage.jar` wird dabei im _current working directory_ gesucht, in dem man sich auf der Konsole gerade befindet. + +Wenn `somePackage.jar` in einem Unterordner `libs` liegen würde, müsste der Aufruf wie folgt aussehen: `java -cp libs/somePackage.jar:. main.Main`. + +Herr Kofler macht zusätzlich Anführungszeichen um den Ausdruck hinter `-cp`. Das ist immer möglich aber nur dann nötig, wenn sich im übergebenen Klassenpfad ein Leerzeichen befindet. +endif::solution[] diff --git a/Fragen/Kap.2.adoc b/Fragen/Kap.2.adoc new file mode 100644 index 0000000..08c8573 --- /dev/null +++ b/Fragen/Kap.2.adoc @@ -0,0 +1,472 @@ +== Variablenverwaltung + +### Frage + +Was heißt `final` als Teil einer Variablendefinition genau? + +ifdef::solution[] +.Antwort +Einer Variablen darf nur genau einmal ein Wert zugewiesen werden. Aber Achtung, siehe S. 83: Wenn der Wert nicht primitiv, sondern ein Referenztyp ist, so kann die Referenz zwar nicht mehr geändert werden, wohl aber kann es möglich sein, die Felder des referenzierten Objekts zu verändern! +endif::solution[] + +### Frage + +`System.out. println(" Umfang: " + umfang);` + +Hier kommt ein Ausdruck der Form `String + double` vor. Welchen Effekt hat dieser Ausdruck? + +ifdef::solution[] +.Antwort +Der `+`-Operator wird hier aufgrund des `String`-Operanden als Konkatenation interpretiert. Der `double`-Wert wird im Hintergrund als Typ angepasst und in seiner Representation als Zeichenkette gewandelt. +endif::solution[] + +### Frage + +Code auf S.63 oben: Wenn ich das in der JShell eingebe, gibt es gar keine Probleme. Irrt Herr Kofler, dass es da ein Problem geben kann? + +ifdef::solution[] +.Antwort +Normalerweise haben Variablen Default-Werte, und alles geht gut: + +---- +jshell> int x,y,z; +x ==> 0 +y ==> 0 +z ==> 0 + +jshell> x = 3; +x ==> 3 + +jshell> y = x + z; +y ==> 3 +---- + +Nicht jedoch, wenn die Variablen lokal in einem Codeblock sind. Ein Codeblock ist durch geschweifte Klammern ausgewiesen. + +---- +jshell> { int x,y,z; x = 3; y = x + z; } +| Error: +| variable z might not have been initialized +| { int x,y,z; x = 3; y = x + z; } +---- +endif::solution[] + +### Frage + +Seite 63: Was ist damit gemeint, dass ein `float` eine Fließkommazahl mit "8 Stellen" darstellt? Geben Sie Beispiele für Zahlen, die nicht darstellbar sind. + +ifdef::solution[] +.Antwort +Ein Beispiel mit acht Stellen, das funktioniert: + +---- +jshell> float x = 0.00000000010f +x ==> 1.0E-10 +---- + +Die Zahl hat mehr als acht Stellen. Was ist gemeint? + +Es sind die acht "geltenden" Stellen gemeint, die ein `float` unterscheiden kann: + +---- +jshell> x = 1.1111111111f +x ==> 1.1111112 +---- + +Hier sind nur acht Stellen zu sehen. Führende oder abschließende Nullen +endif::solution[] + +### Frage + +Unter welchem Namen findet man die Konstanten `+Infinity` und `-Infinity` in der Java-API? + +ifdef::solution[] +.Antwort +---- +jshell> Double.POSITIVE_INFINITY +$9 ==> Infinity + +jshell> Double.NEGATIVE_INFINITY +$8 ==> -Infinity +---- + +Ebenso natürlich unter `Float`. +endif::solution[] + +### Frage + +Warum sind Rundungsfehler bei Fließkommazahlen nicht zu vermeiden? + +ifdef::solution[] +.Antwort +Es gibt Zahlen, die haben unendlich viele Nachkommastellen, wie z.B. Pi, die bei einer endlichen Darstellung immer zu Rundungsfehlern führen. + +---- +jshell> 2/3f +$14 ==> 0.6666667 +---- +endif::solution[] + +### Frage + +Rundungsfehler machen auch einen exakten Vergleich von zwei Fließkommazahlen schwierig. Wie kann man sicher überprüfen, ob eine Variable vom Typ `float` oder `double` "gleich null" ist? Gibt es eine Lösung, die für alle denkbaren Szenarien funktioniert? + +ifdef::solution[] +.Antwort +Beispiel: + +---- +jshell> 0.1 + 0.1 + 0.1 == 0.3 +$15 ==> false +---- + +Bei Fließkommazahlen muss man sich darauf einigen, wieviele Nachkommastellen einem wichtig sind, da man um Rundungseffekte nicht herumkommt. + +---- +jshell> Math.abs(0.1+0.1+0.1-0.3) <= 0.00001 +$16 ==> true +---- + +Eine Standard-Lösung dafür gibt es nicht. +endif::solution[] + +### Frage + +Wie sieht schematisch die Syntax zur Deklaration einer Variablen aus? + +ifdef::solution[] +.Antwort +Buch S.62 (unten): `datentyp varname [ = wert ];` +endif::solution[] + +### Frage + +Warum ist das Erzeugen von Zufallszahlen in Java nicht mit statischen Methoden realisiert? Warum muss man ein Objekt der Klasse `Random` erzeugen? + +ifdef::solution[] +.Antwort +Der Zufall, den ein Computer erzeugt, ist deterministisch, d.h. eine Folge von Zufallszahlen wird durch einen Algorithmus berechnet. Beginnend von einem Startwert (_seed_) wird eine Zahlenfolge berechnet, die die Qualität einer Zufallsfolge hat, aber streng berechnet wird. Der letzte Zufallswert ist Grundlage für den nächsten Zufallswert. Dieser sogenannte Zustand wird in einer Variablen gespeichert. Um mehrere Zufallsgeneratoren betreiben zu können, wir der Generator als Objekt realisiert. +endif::solution[] + +### Frage + +Welchen Wert haben die Variablen `x`, `y` und `z` nach der folgenden Definition: `int x, y, z = 1;`? + +ifdef::solution[] +.Antwort +---- +jshell> int x, y, z = 1; +x ==> 0 +y ==> 0 +z ==> 1 +---- + +Man könnte, sobald die Variablen deklariert sind, einen gleichen Wert für alle Variablen wie folgt setzen: + +---- +jshell> x = y = z = 2 +x ==> 2 + +jshell> x +x ==> 2 + +jshell> y +y ==> 2 + +jshell> z +z ==> 2 +---- +endif::solution[] + +### Frage + +Was ist "implizites Casting"? Geben Sie ein Beispiel. + +ifdef::solution[] +.Antwort +"Casting" heißt "Typanpassung". Implizit ist die Typanpassung dann, wenn sie von Java im Hintergrund für Sie gemacht wird. Addieren Sie z.B. einen `int` und einen `float`, so wird die Ganzzahl von Java implizit in einen Fließkommazahlenwert umgewandelt. +endif::solution[] + +### Frage + +Was ist mit dem Begriff "Überlauf" gemeint? + +ifdef::solution[] +.Antwort +Wenn eine Rechnung den Wertbereich des Zahlentyps überschreitet, spricht man von einem (Zahlen)Überlauf. Java meldet bei einem Überlauf _keinen_ Fehler! +endif::solution[] + +### Frage + +Warum kann man einen `int` implizit zu `long` casten, einen `long` aber nicht zu `int`? + +ifdef::solution[] +.Antwort +Weil beim Casting von `long` zu `int` Information verloren geht. Das macht Java nicht implizit, das müssen Sie im Zweifel explizit tun -- dann müssen Sie aber auch mit den möglichen Folgen leben. +endif::solution[] + +### Frage + +Wie sieht die Syntax für einen expliziten Cast (Typumwandlung) aus? + +ifdef::solution[] +.Antwort +`(typ) wert` +endif::solution[] + +### Frage + +Was versteht man unter einem "Modifizierer" bei der Variablendefinition? Geben Sie ein Beispiel an. + +ifdef::solution[] +.Antwort +Zum Beispiel modifiziert `final` eine Variable. +endif::solution[] + +### Frage + +Welchen Datentyp und welchen dezimalen Wert haben die folgenden Literale? + +* `10` +* `10.0` +* `010` +* `0x10` +* `0b10` + +ifdef::solution[] +.Antwort +* `10` (`int`, die 10) +* `10.0` (`double`, die 10.0) +* `010` (ein `int` in oktaler Kodierung, der Wert ist 8) +* `0x10` (ein `int` in hexadezimaler Kodierung, der Wert 16) +* `0b10` (ein `int` in binärer Kodierung, der Wert 2) +endif::solution[] + +### Frage + +Wie kann man den Wert "eine Million" mit drei Zeichen als Java-Literal darstellen? + +ifdef::solution[] +.Antwort +`1E6` +endif::solution[] + + +// Kapitel 2.4 + +### Frage + +Welche Ausgabe produziert das folgende Programmstück: + +[source,java] +---- +int x = 10; +{ + System.out.println(x); + int x = 5; + System.out.println(x); + { + System.out.println(x); + } +} +---- + +ifdef::solution[] +.Antwort +Das Ergebnis ist: 10, 5, 5 + +.Codeblöcke und Variablen +**** +Codeblöcke definieren eigene Kontexte für sogenannte lokale Variablen. Ein eingegeschachtelter innerer Codeblock hat Zugriff auf die Variablen des umgebenden, äußeren Codeblocks, sofern eine namensgleiche Variable die äußere Variable nicht "überdeckt". Grundsätzlich hat jeder Codeblock Zugriff auf die Felder der Instanz bzw. der Klasse. +**** +endif::solution[] + +### Frage + +Im Anschluss an obigen Code: Was ergibt `{ int x; int x; }`? + +ifdef::solution[] +.Antwort +Doppelte Variablendeklarationen sind verboten! Eine Variable kann in einem Codeblock nur genau einmal deklariert werden. +endif::solution[] + +### Frage + +Ist es eine gute Idee, die drei Punkte eines Dreiecks mit dem folgenden Code zu initialisieren? Warum? + +[source,java] +---- +java.awt.Point p1, p2, p3; +p1 = p2 = p3 = new java.awt.Point(0, 0); +---- + +ifdef::solution[] +.Antwort +Alle drei Punkte haben die gleiche Referenz auf ein und dieselbe Instanz von `Point`. Damit entsteht niemals ein Dreieck aus drei _unterschiedlichen_ Instanzen. +endif::solution[] + +### Frage + +Wie könnte einer dieser ominösen auf S.77 erwähnten "Copy-Konstruktoren" für die Klasse `java.awt.Point` aussehen? + +ifdef::solution[] +.Antwort +[source,java] +---- +class Point { + int x, y; + Point(Point p) { + this(p.x, p.y); + } + Point(int x, int y) { + this.x = x; + this.y = y; + } +} +---- + +Beispiel: + +---- +jshell> Point p = new Point(4,3) +p ==> Point@25bbe1b6 + +jshell> Point p2 = new Point(p) +p2 ==> Point@69ea3742 +---- + +Hier sehen Sie, dass es zwei unterschiedliche Referenzen für `p1` und `p2` gibt. +endif::solution[] + +### Frage + +Was sind _boxing_ und _unboxing_ bei Wrapper-Klassen? + +ifdef::solution[] +.Antwort +Aus einem primitiven Typ einen Referenztyp machen, aus z.B. `int` einen `Integer`, das nennt man _boxing_. Das Gegenteil _unboxing_. +endif::solution[] + +### Frage + +Was passiert bei der Ausführung von folgendem Code: + +[source,java] +---- +Double x = null; +double y = x; +---- + +ifdef::solution[] +.Antwort +---- +jshell> Double x = null +x ==> null + +jshell> double y = x +| java.lang.NullPointerException thrown: +| at (#5:1) +---- +endif::solution[] + +### Frage + +Warum kann man sowohl `int x = Integer.parseInt("123");` als auch `Integer x = Integer.parseInt("123");` schreiben? Was ist der Unterschied? + +ifdef::solution[] +.Antwort +Rückgabetype von `Integer.parseInt("123")` ist ein `int`. Im zweiten Fall der Zuweisung zu `Integer x` wird ein _boxing_ vorgenommen. Im ersten Fall ist `x` ein primitiver Typ, im zweiten bei `Integer x` ein Referenztyp. Wrapperklassen verbrauchen mehr Speicher als ihre primitiven Vorlagen. +endif::solution[] + +### Frage + +Was passiert bei folgender Deklaration `Double x = 10;`? Warum? + +ifdef::solution[] +.Antwort +Die `10` ist der Literal für einen Integer `int`. Bei `double x = 10` wird der `int` implizit auf ein `double` gecastet. Bei `Double x = 10` (Wrapperklasse) geschieht kein implizites Casting, die Implementierung hat das nicht vorgesehen. +endif::solution[] + +### Frage + +Gibt es einen Unterschied zwischen den folgenden beiden Codestücken? + +[source,java] +---- +int x = 10; +double y = x; +---- + +[source,java] +---- +Integer x = 10; +Double y = x; +---- + +ifdef::solution[] +.Antwort +Im ersten Snippet greift das Casting zwischen primitiven Typen. Bei den Wrapperklassen gibt es kein implizites Casting. Das zweite Snippet funktioniert nicht. +endif::solution[] + +### Frage + +Ist `Integer` eine Sub- oder Superklasse von `Long`, oder keins von beidem? + +ifdef::solution[] +.Antwort +Es gibt keinen inneren Bezug zwischen diesen Klassen (also "keins von beidem"). +endif::solution[] + +### Frage + +Welche einzelnen Schritte müssen passieren, um eine Zahl von der Konsole einzulesen? + +ifdef::solution[] +.Antwort +Die Antwort findet sich auf S. 81: + +. Scanner erzeugen +. `System.in` als Quelle angeben +. Auslesen mit `.next()` + +[source,java] +---- +java.util.Scanner scan = new java.util.Scanner(System.in); +String s = scan.next(); +---- +endif::solution[] + +### Frage + +Woher weiß `System.out.println` in dem folgenden Beispiel, wie ein Punkt auf der Konsole aussehen soll? + +[source,java] +---- +System.out.println(new java.awt.Point(0,0)); +---- + +ifdef::solution[] +.Antwort +Die `Point`-Klasse hat eine eigene Implementierung der `toString`-Methode (sie überschreibt die `toString`-Methode der Klasse `Object`), die implizit aufgerufen wird, wenn ein `String``-Kontext angefragt wird. +endif::solution[] + +### Frage + +Definieren Sie einen Enumerationstyp `Ternary`, der die drei Werte `TRUE`, `FALSE`, und `MAYBE` besitzt. + +ifdef::solution[] +.Antwort +[source,java] +---- +enum Ternary { TRUE, FALSE, MAYBE } +---- +endif::solution[] + +### Frage + +Können Enumerationstypen auch Methoden haben? Wie sieht die Deklaration eines solchen Typs aus? + +ifdef::solution[] +.Antwort +Ja. Der Kopf sieht wie bei `enum` aus, der Rumpf kann aber ansonsten wie eine Klasse mit Methoden, Konstruktoren etc. ausgestattet werden. +endif::solution[] diff --git a/Fragen/Kap.3.adoc b/Fragen/Kap.3.adoc new file mode 100644 index 0000000..2330b7b --- /dev/null +++ b/Fragen/Kap.3.adoc @@ -0,0 +1,206 @@ +## Operatoren + +### Frage +Operatoren kommen nur vor in ________? + +ifdef::solution[] +.Antwort +Ausdrücken +endif::solution[] + +### Frage +Was ist mit der Priorität eines Operators gemeint? Geben Sie ein Beispiel an. + +ifdef::solution[] +.Antwort +Die Priorität gibt die Rangfolge der Operatoren bei der Auswertung (Evaluation) an. Sie kennen aus der Arithmetik die Regel zur Rangfolge "Punkt- vor Strichrechnung". +endif::solution[] + +### Frage +Der Minus-Operator "`-`" ist linksassoziativ. Was ist damit gemeint? Erklären Sie das an einem Beispiel. + +ifdef::solution[] +.Antwort +Ein nicht vollständig geklammerter Ausdruck wird entsprechend der Assoziativität der Operatoren geklammert. Bei linksassoziativen Operatoren heißt das, dass der am weitesten links stehende Ausdruck zuerst ausgewertet wird. + +Beispiel: `3 - 4 - 5` wird interpretiert als `(3 - 4) - 5`. +endif::solution[] + +### Frage +Was ist der Unterschied zwischen `&` und `&&`? + +ifdef::solution[] +.Antwort +Das `&` ist ein bitweiser Operator (Ergebnis vom Typ `int` bzw. `long`), das `&&` ein logischer (Ergebnis vom Typ `boolean`). +endif::solution[] + +### Frage +Die Zuweisung ist ein Operator. Das heißt, die Zuweisung hat als Ergebnis einen ___? + +ifdef::solution[] +.Antwort +Wert +endif::solution[] + +### Frage +Anschluss an vorherige Frage: Ist der Zuweisungsoperator rechts- oder linksassoziativ? Können Sie einen Grund angeben, warum es so sein muss? + +ifdef::solution[] +.Antwort +Der Zuweisungsoperator ist rechtsassoziativ. Das ist nötig, damit der Ausdruck `x = y = z = 3` funktioniert. +endif::solution[] + +### Frage +Es gibt drei(!) Kontexte im Zusammenhang von Ausdrücken, in denen runde Klammernpaare `(...)` vorkommen. Welche sind das? + +ifdef::solution[] +.Antwort +Die ersten zwei Kontexte finden Sie in der Operatoren-Tabelle. Den dritten Kontext sollten Sie nicht vergessen! + +* Casting +* Methodenaufrufe +* Klammerung von Ausdrücken zur Veränderung der Priorität (Rangfolge) bei der Evaluation (Auswertung) eines Ausdrucks; Beispiel: `(1 + 2) * 3`, denn in `1 + 2 * 3` greift die Priorität, die Sie als "Punkt- vor Strichrechnung" kennen. + +Die syntaktische Funktion von runden Klammern im Zusammenhang von Anweisungen (die Frage bezog sich auf Ausdrücke!) wie im Kopf einer Schleife, einer `if`-Anweisung, der Deklaration eines Methodenkopfs ist hier nicht gemeint gewesen. Die Frage bezog sich auf Ausdrücke, nicht Anweisungen! +endif::solution[] + +### Frage +Erklären Sie, wie die Kopfzeile im `while` funktioniert: + +`while((line = breader.readLine()) != null) { ... }` + +ifdef::solution[] +.Antwort +. Der Variable `line` wird das Ergebnis des Aufrufs `breader.readLine()` zugewiesen. +. Das Ergebnis dieser Zuweisung ist der neue Wert den `line` erhalten hat. +. Dieser Wert wird mit `null` verglichen. +endif::solution[] + +### Frage +Angenommen, es gäbe den Modulo-Operator `%` in Java nicht. Wie müsste dann eine Implementierung `mod(int x, int y)` z.B. in der `Math`-Klasse aussehen? + +ifdef::solution[] +.Antwort +[source,java] +---- +static int mod(int x, int y) { + int d = x / y; + return x - d * y; +} +---- + +Erinnern Sie sich an das Substitutionsprinzip, das man hier anwenden kann. Der Ausdruck zur Zwischenrechnung, dessen Ergebnis in der Variablen `d` gespeichert wird, kann direkt im `return` die Variable `d` ersetzen. Somit wird der Rumpf der `mod`-Methode zu einem Einzeiler: + +[source,java] +---- + return x - (x / y) * y; +---- +endif::solution[] + +### Frage +Die Kurzform `x += 3` bedeutet ausführlich was? + +ifdef::solution[] +.Antwort +`x = x + 3` +endif::solution[] + +### Frage +Erläutern Sie den Unterschied von `int a = n++;` zu `int a = ++n;`! + +ifdef::solution[] +.Antwort +`int a = n++;` entspricht den Anweisungen `int a = n; n = n + 1;`. Bei `int a = ++n;` dreht sich die Reihenfolge um: `n = n + 1; int a = n;`. +endif::solution[] + +### Frage +Die Vergleichoperatoren wie `>`, `<=`, `==` usw. stehen für welche Typen zur Verfügung? + +ifdef::solution[] +.Antwort +Für alle primitiven Typen außer `boolean` und ihre Wrappertypen. +endif::solution[] + +### Frage +Wann kann man die Methode `compareTo` verwenden? + +ifdef::solution[] +.Antwort +Wenn das Objekt das Interface `Comparable` implementiert. +endif::solution[] + +### Frage +Warum ist es keine gute Idee, zwei Zeichenketten mit `==` zu vergleichen? + +ifdef::solution[] +.Antwort +Weil damit die Identität der Referenzen überprüft wird, nicht aber der Inhalt des Strings. Für Strings und andere komplexe Datentypen sollte man die Methode `equals` verwenden. +endif::solution[] + +### Frage +Was ist der Unterschied von `&` und `&&` bei boolschen Werten? In beiden Fällen ergibt sich immer das gleiche Ergebnis, z.B.: + +---- +jshell> true && false +$11 ==> false +jshell> true & false +$12 ==> false +---- + +ifdef::solution[] +.Antwort +Der Operator `&&` ist _short-circuited_ (engl. für kurzgeschlossen), d.h. wenn an dem linken Operanden schon zu erkennen ist, was das Ergebnis sein muss, wird der rechte Operand überhaupt nicht mehr ausgewertet. +endif::solution[] + +### Frage +Wandeln Sie ein `if (expr1 && expr2) {...}` so um, dass Sie nur `if`-Anweisungen ohne den `&&`-Operator verwenden! + +ifdef::solution[] +.Antwort +`if (expr1) if (expr2) {...}` +endif::solution[] + +### Frage +Gleiche Aufgabe: Umwandlung von `if (expr1 || expr2) { ... }`. + +ifdef::solution[] +.Antwort +`if (expr1) { ... } else if (expr2) { ... }` +endif::solution[] + +### Frage +Multiplizieren Sie eine `int`-Zahl mit `4` ohne die Multiplikation zu verwenden. + +ifdef::solution[] +.Antwort +`zahl << 2` +endif::solution[] + +### Frage +Warum ist der ternäre-Operator nicht mit einem `if` zu vergleichen? Was ist anders? + +ifdef::solution[] +.Antwort +Der ternäre-Operator ist ein Ausdruck (mit einem Ergebnis), das `if` ist eine Anweisung (ohne Ergebnis). +endif::solution[] + +### Frage +Implementieren Sie eine Methode `odd(int n)` (_odd_ heißt "ungerade"), die mithilfe eines Bitoperators ermittelt, ob der übergebene Integer ungerade ist oder nicht. + +ifdef::solution[] +.Antwort +[source,java] +---- +boolean odd(int n) { + return n & 1 == 1; +} +---- +endif::solution[] + +### Frage +`return b == true ? false : true;` Verkürzen Sie die `return`-Anweisung. + +ifdef::solution[] +.Antwort +`return !b;` +endif::solution[] diff --git a/Fragen/Kap.4.adoc b/Fragen/Kap.4.adoc new file mode 100644 index 0000000..68d4a8d --- /dev/null +++ b/Fragen/Kap.4.adoc @@ -0,0 +1,258 @@ +## Verzweigungen und Schleifen + +### Frage +Wie sieht die Syntax einer If-Abfrage aus? + +ifdef::solution[] +.Antwort +---- +if (Bedingung) { + Anweisungen +} +---- +endif::solution[] + +### Frage +Wie sähe der Ausdruck `x = x < 0 ? -x : x` mit einer normalen If-Abfrage aus? + +ifdef::solution[] +.Antwort +---- +if (x < 0) x = -x; +---- +endif::solution[] + +### Frage +Schreiben sie eine If-Abfrage, die abhängig vom Monat in der Integer-Variablen `month` (Der Januar entspricht der `1`) die Jahreszeit ausgibt. (3-5: Frühling, 6-8: Sommer, 9-11: Herbst, 12-2: Winter) + +ifdef::solution[] +.Antwort +[source,java] +---- +if (month >= 3 && month <= 5) { + System.out.println("Frühling"); +} else if (month >= 6 && month <= 8) { + System.out.println("Sommer"); +} else if (month >= 9 && month <= 11) { + System.out.println("Herbst"); +} else { + System.out.println("Winter"); +} +---- +endif::solution[] + +### Frage +Schreiben sie eine Switch-Verzweigung, die abhängig vom Monat in der Integer-Variablen `month` (Der Januar entspricht der `1`) die Jahreszeit ausgibt. (3-5: Frühling, 6-8: Sommer, 9-11: Herbst, 12-2: Winter) + +ifdef::solution[] +.Antwort +[source,java] +---- +switch(month) { + case 3: case 4: case 5: + System.out.println("Frühling"); + break; + case 6: case 7: case 8: + System.out.println("Sommer"); + break; + case 9: case 10: case 11: + System.out.println("Herbst"); + break; + default: + System.out.println("Winter"); +} +---- +endif::solution[] + +### Frage +Was sind die drei Teile des Kopfes einer For-Schleife? + +ifdef::solution[] +.Antwort +. Initialisierung +. Fortsetzungsbedingung +. Schrittanweisung +endif::solution[] + +### Frage +Ist die folgende Schleife syntaktisch korrekt? Falls ja, was wird auf der Konsole ausgegeben? + +[source,java] +---- +int i,j; +for(i = 0, j = 0; i+j < 10; j++, i++) { + System.out.println(i + " " + j); +} +---- + +ifdef::solution[] +.Antwort +Ja, die Schleife ist korrekt. Die Ausgabe lautet wie folgt: + +---- +0 0 +1 1 +2 2 +3 3 +4 4 +---- +endif::solution[] + +### Frage +In Anlehnung an die letzte Frage: Können Sie mit einem einzigen Schleifenkopf eine Schleife schreiben, die die x- und y-Koordinaten aller Pixel eines Bildes mit 8x10 Pixeln durchläuft? + +ifdef::solution[] +.Antwort +[source,java] +---- +int x,y; +for(x = 0, y = 0; x < 8 && y < 10; x = (x + 1) % 8, y = x == 0 ? y + 1 : y) { + System.out.println(x + " " + y); +} +---- +endif::solution[] + +### Frage +Ist die folgende Variante der Schleife auf S. 108 auch korrekt? + +[source,java] +---- +int i; +for(int i=0; i < 10; i++) { + machEtwas(i); +} +---- + +ifdef::solution[] +.Antwort +Nein, diese Schleife ist nicht korrekt. Die Variable `i` im Kopf der `for`-Schleife darf nicht namensgleich mit einer lokalen Variablen im außeren Umfeld der `for`-Schleife sein. +// TODO hier muss eigentlich noch etwas mehr erklärt werden +endif::solution[] + +### Frage +Ist `for(int i; i < 10; i++) { ... }` korrekt? + +ifdef::solution[] +.Antwort +Der Code ist nicht korrekt. Die Variable `i` wird nicht initialisiert. +endif::solution[] + +### Frage +Was ist bei Schleifen zu beachten deren Zählvariable vom Typ `float` oder `double` ist? + +ifdef::solution[] +.Antwort +Die Fortsetzungsbedingung sollte kein exakter Vergleich sein, da dieser eventuell durch Rundungsfehler nie zutrifft. +endif::solution[] + +### Frage +Kann der Zähler einer `for`-Schleife auch den Typ `char` haben? + +ifdef::solution[] +.Antwort +Ja, da ein `char` immer auch einem Zahlwert entspricht (entsprechend der UTF-16-Kodierung). +endif::solution[] + +### Frage +Ein Student und eine Studentin schreiben den folgenden `for`-Kopf, um die Summe der Zahlen von 1 bis 50 zu berechnen: `for(i = 1, sum = 0; i <= 50; sum += i++);` Was sagt Ihnen Ihr Programmierverstand? + +(Übrigens: Der Kopf der Schleife ist syntaktisch korrekt, da liegt nicht das Problem!) + +ifdef::solution[] +.Antwort +Die Variable `sum` wird innerhalb der Schleife definiert, kann aber außerhalb der Schleife nicht mehr ausgelesen werden. +endif::solution[] + +### Frage +Schreiben Sie die folgende For-each-Schleife mit einer normalen for-Schleife: `for(int x: ar) { System.out.println(x); }` + +ifdef::solution[] +.Antwort +[source,java] +---- +for(int i = 0; i < ar.length; i++) { + System.out.println(ar[i]); +} +---- +endif::solution[] + +### Frage +Was ist der Unterschied zwischen einer while-Schleife und einer do-while-Schleife? In welchem Fall ist die eine sinnvoller, in welchem die andere? + +ifdef::solution[] +.Antwort +Die do-while-Schleife wird immer mindestens einmal durchlaufen. Wenn man z.B. einen Verbindungsversuch über das Netzwerk im Fehlerfall wiederholen möchte, wäre eine do-while-Schleife passender, da der Verbindungsversuch ja auf jeden Fall mindestens einmal stattfinden sollte. +endif::solution[] + +### Frage +Man kann jede `for`-Schleife in eine `while`- bzw. `do/while`-Schleife umwandeln. Stimmt das? + +ifdef::solution[] +.Antwort +Ja. +endif::solution[] + +### Frage +Beschreiben Sie die Ausführung einer `for`-Schleife: + +`for(init ; cond ; change) { body ; }` Welche Anteile werden in welcher Reihenfolge wiederholt ausgeführt? + +ifdef::solution[] +.Antwort +. `init` +. falls `cond`, dann `body` +. `change` +. gehe zu 2. +endif::solution[] + +### Frage +Herrn Kofler kräuseln sich die Fußnägel, wenn Sie Fließkommazahlen im Kopf einer `for`-Schleife verwenden. Warum? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +`for(int i = 0; i < 100; i++) { if (i % 2 == 0) System.out.println(i); }` + +Vervollständigen Sie den folgenden Code so, dass er das gleiche tut wie der oben stehende Code: + +[source,java] +---- +int i = 0; +while(true) { + // hier bitte Code einfügen + System.out.println(i); + // hier bitte Code einfügen +} +---- + +Sie dürfen bereits bestehende Zeilen nicht mehr ändern, nur welche hinzufügen. + +ifdef::solution[] +.Antwort +[source,java] +---- +int i = 0; +while(true) { + if(i >= 100) break; + if(i % 2 != 0) continue; + System.out.println(i); + i++; +} +---- +endif::solution[] + +### Frage +Der Kopf `for(int i = 1; ; i++)` sei gegeben, Sie dürfen ihn nicht verändern. Allerdings darf die Schleife nur für `i` bis 50 laufen. Retten Sie das im Rumpf! + +ifdef::solution[] +.Antwort +[source,java] +---- +for(int i = 1; ; i++) { + if (i > 50) break; +} +---- +endif::solution[] diff --git a/Fragen/Kap.5.adoc b/Fragen/Kap.5.adoc new file mode 100644 index 0000000..fdd3bd5 --- /dev/null +++ b/Fragen/Kap.5.adoc @@ -0,0 +1,123 @@ +== Arrays + +### Frage +Wie lauten die zwei Syntaxvarianten zur Deklaration einer (eindimensionalen) Array-Variable? + +ifdef::solution[] +.Antwort +---- +datentyp[] var +datentyp var[] +---- +endif::solution[] + +### Frage +Kann die Größe von Java-Array nachträglich verändert werden? Warum/Warum nicht? + +ifdef::solution[] +.Antwort +Die Größe eines Arrays kann _nicht_ nachträglich verändert werden. Arrays belegen einen zusammenhängenden Platz im Arbeitsspeicher, der Platz ist vorreserviert und kann nicht mehr angepasst werden. +endif::solution[] + +### Frage +Seite 121: "Arrays können auch in `for-each`-Schleifen durchlaufen werden. Die Array-Elemente können dann jedoch nur gelesen, nicht aber verändert werden." + +Warum können die Elemente nicht verändert werden? Erläutern Sie. + +ifdef::solution[] +.Antwort +Die Elemente werden einzeln einer Variable zugewiesen (Ihnen fehlt z.B. auch der Index für einen Zugriff). +endif::solution[] + +### Frage +Seite 121: Was ist wohl mit "echten mehrdimensionalen Arrays" gemeint? + +ifdef::solution[] +.Antwort +Die Speicherorganisation ist nicht verschachtelt, sondern sequentiell. +// TODO +endif::solution[] + +### Frage +Seite 122: Warum `for(int j=0; j char[] ar = new char[1]; +ar ==> char[1] { ' ' } +---- +Das ist kein "echtes" Leerzeichen (im Sinne der "Leertaste" auf Ihrer Tastatur), sondern das Unicode "Null"-Zeichen. +endif::solution[] + +### Frage +Welchen Typ hat ein Array, das auf der Konsole als `[Ljava.lang.String;@ff5b51f` ausgegeben wird? + +ifdef::solution[] +.Antwort +---- +String[] +---- +endif::solution[] + +### Frage +Wie könnte man eine "schönere" String-Darstellung des Arrays aus der letzten Aufgabe erhalten? + +ifdef::solution[] +.Antwort +Mit der `Arrays.toString`-Methode. +endif::solution[] + +### Frage +Was ist eine Shallow-Copy? + +ifdef::solution[] +.Antwort +Man kopiert das Arrays. Enthält das Arrays Referenzen, werden auch die Referenzen kopiert, nicht die referenzierten Elemente. Das heißt, die Referenzen werden zwischen dem ursprünglichen und der Kopie geteilt. +endif::solution[] + +### Frage +Worauf muss man beim Kopieren von mehrdimensionalen Arrays achten? + +ifdef::solution[] +.Antwort +Die `clone`-Methode (und auch andere Kopiermethoden der Java-API) erzeugen nur eine _Shallow-Copy_, bei der nur auf der obersten ebene Kopiert wird. Die einzelnen Teil-Arrays sind immer noch identisch (gleiche Referenz), so dass Änderungen an der Kopie sich auf das Original auswirken. +endif::solution[] + +### Frage +Was müsste man tun, um eine Deep-Copy eines Arrays zu erhalten? + +ifdef::solution[] +.Antwort +Man muss dann auch die referenzierten Instanzen kopieren und die Referenzen innerhalb dieser Instanzen etc. +endif::solution[] + +### Frage +Es gibt zwei Probleme mit dem folgenden Snippet. Welche? +`Array.sort(new int[]{5,7,-1,3,2})` + +ifdef::solution[] +.Antwort + +* Es fehlt das "s": `Arrays` +* Das Array wird an der Stelle sortiert, aber man kommt an das Ergebnis nicht dran, weil man keine Referenz auf das Array mehr hat. +endif::solution[] + +### Frage +Seite 126: Ändern Sie die Deklaration des Arrays so, dass der Code von Herrn Kofler auf die Nase fällt. Sie dürfen weder den Typ noch den Namen des Arrays verändern. + +ifdef::solution[] +.Antwort +---- +int x[] = { };` +---- +Wenn es kein Element im Array gibt, wird `x[0]` eine Ausnahme werfen! +endif::solution[] diff --git a/Fragen/Kap.6.adoc b/Fragen/Kap.6.adoc new file mode 100644 index 0000000..3f06f86 --- /dev/null +++ b/Fragen/Kap.6.adoc @@ -0,0 +1,340 @@ +== Zeichenketten + +### Frage +Wir ist die Schreibweise für ein Einzelzeichen-Literal? + +ifdef::solution[] +.Antwort +---- +'Buchstabe' +'\uXXXX' //Unicode-Escape +'\n' //Newline +'\t' //Tabulator +---- +endif::solution[] + +### Frage +Bei Literalen für Einzelzeichen hat der Backslash `\` eine Sonderfunktion: Welche? (Wie nennt man den "Backslash"? Er ist das sogenannte ___zeichen.) + +ifdef::solution[] +.Antwort +Der Backslash ist ein _Escape-Zeichen_ (bzw. deutsch "Ausstiegszeichen"). +Er dient dazu Unicode-Symbole und Steuerzeichen zu definieren, die nicht auf der Tastatur zu finden sind. +endif::solution[] + +### Frage +Was bedeutet "Unicode"? + +ifdef::solution[] +.Antwort +"Unicode" ist eine Zeichentabelle, die einer Zahl ein Zeichen zuordnet. +endif::solution[] + +### Frage +Wie prüfen Sie, ob ein `char c` eine Ziffer oder ein Großbuchstabe ist? + +ifdef::solution[] +.Antwort +Mit der Methode `Character.isDigit` bzw. `Character.isUpper`. +endif::solution[] + +### Frage +Definieren Sie eine `char`-Variable, die das Unicode-Symbol "Airplane" (U+2708) enthält. + +ifdef::solution[] +.Antwort +---- +char c = '\u2708'; +---- +endif::solution[] + +### Frage +Ich gebe Ihnen ein geheimnisvolles Einzelzeichen `geheim`. Ermitteln Sie, welches Einzelzeichen `geheim` vorangeht und welches ihm folgt. + +ifdef::solution[] +.Antwort +Mit `(char) (geheim + 1)` bzw. `(char) (geheim - 1)`. +endif::solution[] + +### Frage +Was ergibt `'T' + 'H' + 'M'`? + +ifdef::solution[] +.Antwort +---- +233 +---- +endif::solution[] + +### Frage +Was ergibt `"" + 'T' + 'H' + 'M'`? + +ifdef::solution[] +.Antwort +---- +"THM" +---- +endif::solution[] + +### Frage +Was ergibt `'T' + 'H' + 'M' + ""`? + +ifdef::solution[] +.Antwort +---- +"233" +---- + +Erklärung: Der Operator `+` ist linksassoziativ. D.h. der Ausdruck wird wie folgt geklammert: `(('T' + 'H') + 'M') + ""` +endif::solution[] + +### Frage +Wie machen Sie aus `"MNI"` eine Folge von Einzelzeichen? + +ifdef::solution[] +.Antwort +---- +"MNI".toCharArray() +---- +endif::solution[] + +### Frage +Erstellen Sie die Zeichenkette `"C:\Users\mni\oop\"` (Windows-Stil) als Pfad-Angabe unter Java. + +ifdef::solution[] +.Antwort +---- +String file = "C:\\Users\\mni\\oop\\"; + +String file = "C:" + File.separtor + "Users" + File.separator + "mni" + File.separator + "oop" + File.separator +---- +endif::solution[] + +### Frage +Beschreiben Sie den visuellen Effekt der Zeichenkette `"\n\tTest\n"`. + +ifdef::solution[] +.Antwort +---- + + Test + +---- + +Erklärung: `\n` leitet einen Zeilenumbruch ein, `\t` steht für ein Tabulatorzeichen. +endif::solution[] + +### Frage +Initialisieren Sie `String s` als leere Zeichenkette! + +ifdef::solution[] +.Antwort +---- +String s = ""; +---- + +Hinweis: `String s;` bzw. `String s = null;` wäre keine korrekte Lösung, da eine leere Zeichenkette trotzdem ein vollwertiges String-Objekt ist. +endif::solution[] + +### Frage +Gegeben sei das Array `String[] s`. Wir möchten davon eine Kopie anlegen. Muss man eine _deep copy_ anfordern, reicht eine _shallow copy_ oder genügt gar eine einfache Zuweisung? + +ifdef::solution[] +.Antwort +Strings sind _immutable_ (dt. unveränderlich). D.h. ein einmal erzeugtes String-Objekt kann sich nicht mehr verändern. Daher reicht es in diesem Fall eine _shallow copy_ des Arrays zu machen. +endif::solution[] + +### Frage +Warum sollte man eine Zeichenkette niemals mit `==` vergleichen? + +ifdef::solution[] +.Antwort +Der Operator `==` überprüft bei komplexen Typen wie String nur, ob es sich um die selbe Referenz handelt (d.h. ob die Daten an der gleichen Stelle im Speicher stehen). Mit dem Inhalt des Strings hat das nichts zu tun. +endif::solution[] + +### Frage +Ergibt `"abc" == "abc"` immer `true` oder kann es vielleicht auch mal `false` ergeben? + +ifdef::solution[] +.Antwort +Dieser Vergleich ergibt immer `true`, da String-Literale vom Compiler so optimiert werden, dass zwei gleiche Literale auch die gleiche Referenz erhalten (Strings werden _internalisiert_). +endif::solution[] + +### Frage +Was liefert der Vergleich `"aaa" > "abc"`? + +ifdef::solution[] +.Antwort +Dieser Vergleich ist ein Syntaxfehler. Der Operator `>` ist nur für primitive Typen definiert. Zum Vergleichen von Strings braucht man die Methode `compareTo`. +endif::solution[] + + +### Frage +Was ergibt `String.valueOf("String")`? + +ifdef::solution[] +.Antwort +---- +"String" +---- +endif::solution[] + +### Frage +Welchen Formatierungscode brauchen Sie, um eine Fließkommazahl mit drei Nachkommastellen darzustellen? + +ifdef::solution[] +.Antwort +`%.3f` +endif::solution[] + +### Frage +Alles happy? `int i = 3; System.out.println(i.toString());` + +ifdef::solution[] +.Antwort +Hier gibt es einen Fehler, weil `i` vom primitiven Typ `int` ist. Primitive Typen haben keine Methoden, auch kein `toString`. +endif::solution[] + +### Frage +Warum gibt es `String.valueOf()`, wenn es doch die `toString()`-Methode gibt? + +ifdef::solution[] +.Antwort +Weil `toString()` nicht auf primitive Datentypen angewendet werden kann. +endif::solution[] + +### Frage +Trennen Sie die Zeichenkette `C:\Users\mni\oop\` mit der Methode `split` in die einzelnen Pfadbestandteile auf. Welches Problem ergibt sich dabei? + +ifdef::solution[] +.Antwort +---- +String path = "C:\\Users\\mni\\oop\\"; +path.split("\\\\"); +---- + +Die Methode `split` erwartet einen regulären Ausdruck. Der Backslash hat auch in regulären Ausdrücken eine besondere Bedeutung. Der String `"\\"` entspricht dem regulären Ausdruck `\`, der selbst keine Bedeutung hat (ein Escape-Zeichen ohne nachfolgendes Zeichen). Um den regulären Ausdruck `\\` zu erhalten, der auf das Zeichen `\` matcht, muss man also tatsächlich `"\\\\"` schreiben. +endif::solution[] + +### Frage +Geben Sie ein String-Format an, das die Zahl `12.345678f` nur mit exakt zwei Nachkommastellen angibt. (edited) + +ifdef::solution[] +.Antwort +`System.out.printf("%.2f", 12.345678f)` +endif::solution[] + +### Frage +Gegeben sei `float[] floats = { 1.234f, 12.56f, 123f }`. Gehen Sie in einer Schleife durch das Array und geben Sie die Zahlen untereinander aus. Die Kommas sollen positionsgleich untereinander stehen, eine Nachkommastelle ist relevant. (edited) + +ifdef::solution[] +.Antwort +---- +for(float f: floats) { + printf("%5.1f\n", f); +} +---- +endif::solution[] + +### Frage +Welcher Hex-Darstellung entspricht 2017? + +ifdef::solution[] +.Antwort +---- +printf("%04X", 2017); +---- +endif::solution[] + +### Frage +In einer String-Variable namens `geheim` steht ein Dateiname. Finden sie die Dateiendung heraus (der Teil nach dem letzten Punkt im Namen). + +ifdef::solution[] +.Antwort +---- +String geheim = "test.hallo.txt"; + +// Variante 1: split +String[] split = geheim.split("\\."); +System.out.println(split[split.length - 1]); + +//Variante 2: lastIndexOf +System.out.println(geheim.substring(geheim.lastIndexOf(".")+1)); +---- +endif::solution[] + +### Frage +Sie treffen auf Aliens, die Ihnen auf eine Tafel die Zahl `"110"` schreiben. Sie stellen fest, dass die Aliens an ihren beiden Händen insgesamt 6 Finger haben. Wie lautet die Zahl also im 6er-System? + +(Schon "Arrival" im Kino geschaut?) + +ifdef::solution[] +.Antwort +---- +Integer.parseInt("110", 6); +---- +endif::solution[] + +### Frage +`Long.parseLong("55",5)` -- Autsch! Warum? + +ifdef::solution[] +.Antwort +Es gibt kein Zeichen `5` im 5er-System. +endif::solution[] + +### Frage +`Long.parseLong("55L")` -- Autsch! Schade! Warum schade? + +ifdef::solution[] +.Antwort +Die Methode `parseLong` parst nur Zahlen, das `L` führt daher zu einem Fehler. +endif::solution[] + +### Frage +In welchen Fällen ist der Einsatz der Klasse `StringBuilder` sinnvoll? + +ifdef::solution[] +.Antwort +Wenn viele Teilstrings mit `+` konkateniert werden müssten. Der `StringBuilder` spart in diesem Fall viel Rechenzeit, da bei einer normalen Konkatenation der gesamte String kopiert werden muss. +endif::solution[] + +### Frage +Sie wollen sicherstellen, dass Java bei der Übersetzung Ihres Java-Programms die Java-Datei in der Kodierung UTF-8 einliest. Wie machen Sie das? + +ifdef::solution[] +.Antwort +---- +javac -encoding UTF8 ... +---- +endif::solution[] + +### Frage +`StringBuilder s1 = new StringBuilder("Hallo "); StringBuilder s2 = new StringBuilder("Welt");` Wären `s1` und `s2` Strings, so könnten Sie beide mit `s1+s2` konkatenieren. Wie lösen Sie das Problem vergleichbar hier? + +ifdef::solution[] +.Antwort +---- +s1.append(s2.toString()); +---- +endif::solution[] + +### Frage +Das Programm auf Seite 147/148 zählt Groß- und Kleinbuchstaben in einem String. Wäre statt der `if`-Anweisungen nicht ein `switch` passender und würde den Code lesbarer machen? + +ifdef::solution[] +.Antwort +Das switch müsste jeden einzelnen Buchstaben als case definieren. Man kann keine dynamischen cases wie `case c.isDigit()` definieren. +endif::solution[] + +### Frage +Zeichensatzprobleme gibt es nicht nur in Quellcodedateien, sondern auch immer dann wenn Zeichenketten von außerhalb in das Programm kommen oder ausgegeben werden (z.B. über das Netzwerk oder aus einer Datei). Um zwischen verschiedenen Kodierungen wechseln zu können bietet die Klasse `String` den Konstruktor `String(byte[], Charset)` und die Methode `getBytes(Charset)`.Wandeln Sie das Zeichen `ä` (unicode `\u00e4`) erst in US_ASCII um und lesen das resultierende Byte-Array wieder so ein als wäre es UTF_8-kodiert. + +ifdef::solution[] +.Antwort +---- +import java.nio.charset.StandardCharsets; +byte[] ascii = "\u00e4".getBytes(StandardCharsets.US_ASCII); +new String(ascii, StandardCharsets.UTF_8).getBytes(); +---- +endif::solution[] diff --git a/Fragen/Kap.8.adoc b/Fragen/Kap.8.adoc new file mode 100644 index 0000000..117be23 --- /dev/null +++ b/Fragen/Kap.8.adoc @@ -0,0 +1,357 @@ +== Methoden + +### Frage +Haben Klassen Methoden? Oder haben Objekte Methoden? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +In Java gibt es Klassen, die nur statische Methoden haben. Macht das Sinn? Nennen Sie ein Beispiel. + +ifdef::solution[] +.Antwort +Ja. So z.B. bietet die Klasse `Math` statische Methoden an. Wir brauchen keine Instanzen, da mathematische Funktionen zustandslos sind. +endif::solution[] + +### Frage +Wie sieht der syntaktische Aufbau des Kopfes einer Methode aus? Beginnen Sie beim Rückgabetyp. + +ifdef::solution[] +.Antwort +---- +rückgabetyp methodName(typ1 parName1, typ2 parName2) +---- +endif::solution[] + +### Frage +Jemand schreibt die Methode `void Sort(String[] passwords)` und bekommt sofort Schelte von seinen Kolleg(inn)en. Warum? + +ifdef::solution[] +.Antwort +Methodennamen niemals mit einem Großbuchstaben beginnen! Es sollte `sort` heißen. +endif::solution[] + +### Frage +Wenn `Arrays.sort()` ein bestehendes Array verändern kann, könnte man dann auch eine Methode `void increment(int i) {...}` schreiben, die eine bestehende Integer-Variable verändert? + +ifdef::solution[] +.Antwort +Der Aufruf von `increment(j)` führt dazu, dass der Wert hier der Variablen `j` an `i` zugewiesen wird (Fachbegriff: _pass by value_). Damit können aber keine Änderungen am Wert von `j` bewirkt werden. +endif::solution[] + +### Frage +In jedem Java-Programm muss es genau eine `main`-Methode geben. Wie muss der Kopf der `main`-Methode aussehen? + +ifdef::solution[] +.Antwort +`public static void main(String[] args)` +endif::solution[] + +### Frage +`static Car getCar() { return this.car; }` Autsch! Warum? + +ifdef::solution[] +.Antwort +In einer statischen Methode darf niemals `this` genutzt werden. +endif::solution[] + +### Frage +In welchem Fall _muss_ eine Methode in ihrem Rumpf eine `return`-Anweisung enthalten? + +ifdef::solution[] +.Antwort +Wenn der Rückgabetype `void` ist, kann, muss aber kein `return` (ohne Rückgabewert) im Rumpf vorkommen. Ansonsten muss immer mindestens ein `return` im Rumpf mit einem Rückgabewert vorkommen. +endif::solution[] + +### Frage +Die Methode `String.valueOf` muss mit sehr vielen verschiedenen Datentypen als Parameter umgehen. Wie kann es sein, dass man an die Methode sowohl einen `double` als auch einen `char` übergeben kann und trotzdem immer das richtige Ergebnis bekommt? + +ifdef::solution[] +.Antwort +Unter dem gleichen Namen, hier `valueOf`, gibt es verschiedene Methodenköpfe (und damit auch verschiedene Implementierungen) die jeweils verschiedene Typen im Kopf für den Parameter formulieren. (Fachbegriff: _method dispatch_ nennt sich der Mechanismus, die richtige Methodenimplementierung herauszusuchen.) +endif::solution[] + +### Frage +`float numberOne() { return 1.0; }` Autsch oder nicht Autsch, das ist hier die Frage! + +ifdef::solution[] +.Antwort +Autsch, da `1.0f` im `return``stehen muss. +endif::solution[] + +### Frage +Könnte man den Parameter `args` der Main-Methode auch als eine variable Anzahl von Strings definieren? Probieren Sie es aus! + +ifdef::solution[] +.Antwort +Ja, darf man! // Check TODO +endif::solution[] + +### Frage +Eine Methode sei mit einem Argument deklariert (keine Überladung), sie wird jedoch mit drei Argumenten aufgerufen -- und Java akzeptiert das klaglos. Wie muss die Methode deklariert worden sein? + +ifdef::solution[] +.Antwort +Wieder ein `...` (Varargs). +endif::solution[] + +### Frage +Was ist der sogenannte _CallStack_? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Ist die folgende Definition von überladenen Methoden zulässig? + +[source,java] +---- +float foo(int x) { return x; } +float foo(int ... x) { return x[0]; } +---- + +ifdef::solution[] +.Antwort +Der Aufruf scheint mehrdeutig zu sein. Bei dem Aufruf mit einem Argument wird die spezifischere Deklaration (die erste) ausgewählt. +endif::solution[] + +### Frage +Auf welche Weisen kann man eine Methode "überladen"? + +ifdef::solution[] +.Antwort +Durch die +* Anzahl und den +* Typ +der Parameter. +endif::solution[] + +### Frage +`void doStuff(int ... x, String y) { ... }` - Geht das? + +ifdef::solution[] +.Antwort +Varargs müssen immer am Ende deklariert sein. +endif::solution[] + +### Frage +Was ist der Grund, wenn der CallStack überläuft? + +ifdef::solution[] +.Antwort +endif::solution[] + +### Frage +Definieren Sie eine Methode `floatEquals`, die zwei float-Werte `a` und `b` und einen optionalen dritten float Wert `tolerance` übernimmt und einen `boolean` zurückgibt. + +ifdef::solution[] +.Antwort +Varargs sind keine Lösung, weil sonst auch mehr als drei Argumente möglich wären. +---- +boolean floatEquals(float a, float b) { ... } +boolean floatEquals(float a, float b, float tolerance) { ... } +---- +endif::solution[] + +### Frage +Welche Informationen werden auf dem CallStack gespeichert? + +ifdef::solution[] +.Antwort +endif::solution[] + +### Frage +Wenn man einen Parameter mit `final` ausweist verhindert das ... was? + +ifdef::solution[] +.Antwort +Man dem Wert des Parameters keinen neuen Wert zuweisen. +endif::solution[] + +// ab hier Kap. 8.3 folgende + +### Frage + +[source,java] +---- +void foo() { + return; + System.out.println("returned"); +} +---- +Geht das? + +ifdef::solution[] +.Antwort +Ein Methodenaufruf endet bei dem `return`, die nachfolgende Codezeile wird niemals ausgeführt und ist damit toter Code (_dead code_). Der Java-Compiler erkennt das und übersetzt deshalb den Code nicht, in der Annahme, dass das keine Absicht sein kann. +endif::solution[] + +### Frage + +[source,java] +---- +void bar() { + if (true) return; + System.out.println("returned"); +} +---- +Und das? + +ifdef::solution[] +.Antwort +Der Code nach dem `if` wird vom Compiler nicht als toter Code erkannt, da er die Konsequenz von dem `true` nicht nachvollzieht. +endif::solution[] + +### Frage +`return(0)` statt `return 0` ist in Java zulässig. Geht auch `return()` statt `return` für void-Methoden? + +ifdef::solution[] +.Antwort +Nein. Die Klammern im `return` sind möglich, weil man Ausdrücke grundsätzlich klammern kann. Ein `()` ist kein gültiger Ausdruck. +endif::solution[] + +### Frage +Läuft der Code? +[source,java] +---- +void flopp(int n) { + if (true) return; +} +---- + +ifdef::solution[] +.Antwort +Ja, sie läuft. +endif::solution[] + +### Frage +Und dieser hier? +[source,java] +---- +int flopp(int n) { + if (true) return 0; +} +---- + +ifdef::solution[] +.Antwort +Java meldet "missing return statement". Den Fall hatten wir oben schon. Java erwartet, dass es nach dem `if` (wenn die Bedingung nicht greift), weiter geht und dort auch ein `return` folgen muss. +endif::solution[] + +### Frage +Was passiert bei der Ausführung dieser Methode? +[source,java] +---- +float baz(float x) { + try { + if (x < 0) return 0; + x *= 2; + return x; + } finally { + System.out.println("returned from call baz(" + x + ")"); + } +} +---- + +ifdef::solution[] +.Antwort +Das `finally` wird immer ausgeführt, egal ob die Exception geworfen wurde oder nicht -- sogar noch "nach" dem `return`. +.`finally` schlägt `return` +**** +Mit `finally` ist es möglich, dass "nach" einem `return` noch Code ausgeführt wird! +**** +endif::solution[] + +### Frage +[source,java] +---- +int rek(int n) { + if(n == 0) return 0; + return 2 * rek(n - 2); +} +---- +Geht das gut? + +ifdef::solution[] +.Antwort +Für große `n` wird der CallStack vorzeitig erschöpft, so dass kein Ergebnis berechnet wird. +endif::solution[] + +### Frage +Bei der Rekursion unterscheidet man stets den Abbruch- und den Wiederholungsfall. Erklären Sie das am Beispiel der rekursiven Implementierung der Fakultätsfunktion. + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +[source,java] +---- +int fib(int n) { return n < 2 ? n : fib(n-1) + fib(n-2); } +---- + +Listen Sie die Aufrufe der Methode `fib` nacheinander auf, die ausgelöst werden, wenn `int x = fib(4);` ausgeführt wird. + +ifdef::solution[] +.Antwort +---- +fib(4) -> return fib(3) + ... + +-> return fib(2) + ... + +-> return fib(1) + ... + 1 + fib(0) + 0 +---- +endif::solution[] + +### Frage +[source,java] +---- +boolean isOdd(int n) { + return n >= 0 && (n == 0 || isOdd(n-2)); +} +---- +Funktioniert das? + +ifdef::solution[] +.Antwort +Ja. Das Fazinierende ist, dass es kein `if` gibt. Die Fallunterscheidung kommt durch das `&&` zustande, dass die rechte Seite nur auswertet, wenn die linke ein `true` ergibt. +endif::solution[] + +### Frage +Es gibt einen Klassiker zur sogenannten wechselseitigen Rekursion: Methode `boolean isOdd(int n)` ruft `boolean isEven(int n)` auf und umgekehrt. Dabei reduziert jede Methode den Zahlenwert um 1, bevor der Gegenpartner aufgerufen wird. Was ist der jeweilige Abbruchfall? Implementieren Sie diese Rekursion. + +ifdef::solution[] +.Antwort +---- +boolean isOdd(int n) { + if (n == 0) return false; + return isEven(n-1); +} + +boolean isEven(int n) { + if (n == 0) return true; + return isOdd(n-1); +} +---- +endif::solution[] + +### Frage +---- +int foo(int n) { + if (n > 100) return n-10; + else return foo(foo(n+11)); +} +---- +WTF? Ist das erlaubt? + + +ifdef::solution[] +.Antwort +Verstehen Sie auf den ersten Blick, was der Code macht? Das ist die McCarthy-Funktion, die schwer zu durchblicken ist. +endif::solution[] diff --git a/Fragen/Kap.9.adoc b/Fragen/Kap.9.adoc new file mode 100644 index 0000000..128b2c0 --- /dev/null +++ b/Fragen/Kap.9.adoc @@ -0,0 +1,170 @@ +== Exceptions + +### Frage +Wenn eine Exception geworfen wird, dann sieht sich Java zur Laufzeit außerstande ...? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Kann `javac`, der Java-Compiler, eine Exception zu Ihrem Code werfen? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Die Informationen, die zu einer Exception geführt haben, werden wie kommuniziert? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Wie heißt die oberste Klasse in der Exception-Hierarchie? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Was ist ein _Stack Trace_? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Wenn eine Exception vom Typ `Error` geworfen wird, dann hat das was für Konsequenzen? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Was unterscheidet Exceptions, die von `RuntimeException` erben von anderen Subklassen von `Exception`? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Warum ist der Name `RunTimeException` für eine der Exception-Klassen ein wenig unsinnig? (edited) + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +In welchem Fall muss im Kopf einer Methode `throws` samt Angabe der möglichen Ausnahme(n) stehen? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Wenn `catch`-Blöcke identischen Code haben, bietet sich eine Verkürzungsform an. Beschreiben Sie den syntaktischen Aufbau des "verkürzten" `catch`-Kopfes. + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Die StackTrace eines `StackOverflowError` ist sehr lang. Warum? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +`try { /* some code */ }` and there is something wrong. + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Was ist der Vorteil eines _try-with-resources_ gegenüber einem normalen `finally`-Block? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Anschlussfrage: Was ist eine _resource_? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Ein Student schreibt folgende main-Methode und wird sofort dafür gescholten. Warum? +[source,java] +---- +public static void main(String[] args) throws Throwable { + // ... +} +---- + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + + +### Frage +Was macht die `assert`-Anweisung? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +[source,java] +---- +try { + // dangerous stuff +} catch (Exception e) { + e.printStackTrace(); +} catch (NumberFormatException nfe) { + System.err.println("Stupid user input!") +} +---- +Geht das? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Sie haben in Ihrem Code `assert`-Anweisungen, die eigentlich eine Exception auslösen müssten (Beispiel: `assert false;`). Die Exceptions bleiben aus. Was ist los? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] + +### Frage +Kann man selbst Exceptions definieren? + +ifdef::solution[] +.Antwort +-- TODO -- +endif::solution[] diff --git a/Fragen/images/CollectionBilder.jpg b/Fragen/images/CollectionBilder.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cac7fc9dec0ef029548e6945aa24ad350bd28ad6 GIT binary patch literal 501802 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�n|mZ2JWq=B1CumRAvj4A7Ql+6M8s`{38- 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 z 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