Java: Was gibt der Code aus?
Jede Lösung wurde mit OpenJDK 21 ausgeführt und geprüft.
- String-Verkettung ★☆☆ Strings · Operatoren ✓ gelöst
Was gibt dieses Programm aus?
public class Main { public static void main(String[] args) { System.out.println(1 + 2 + "3" + 4 + 5); } }Lösung anzeigen
Ausgabe:
3345
Auswertung von links nach rechts: 1 + 2 = 3 (Zahl), dann 3 + "3" = "33" (String). Ab da ist alles String-Verkettung: "334", dann "3345".
- Ganzzahldivision ★☆☆ Arithmetik ✓ gelöst
Was gibt dieses Programm aus?
public class Main { public static void main(String[] args) { System.out.println(7 / 2); System.out.println(7 / 2.0); System.out.println(-7 / 2); System.out.println(-7 % 3); } }Lösung anzeigen
Ausgabe:
3 3.5 -3 -1
int / int schneidet die Nachkommastellen ab, und zwar Richtung 0 (also -3, nicht -4). Sobald ein Operand double ist, wird mit Komma gerechnet. Der Rest hat in Java immer das Vorzeichen des Dividenden: -7 % 3 = -1.
- Switch ohne break ★☆☆ Kontrollfluss ✓ gelöst
Was gibt dieses Programm aus?
public class Main { public static void main(String[] args) { int x = 2; switch (x) { case 1: System.out.print("1"); case 2: System.out.print("2"); case 3: System.out.print("3"); default: System.out.print("d"); } } }Lösung anzeigen
Ausgabe:
23d
Ohne break "fällt" die Ausführung in alle folgenden Fälle durch (Fall-through). Einstieg bei case 2, dann weiter durch case 3 und default.
- Gleitkomma ★☆☆ Arithmetik · double ✓ gelöst
Was gibt dieses Programm aus?
public class Main { public static void main(String[] args) { System.out.println(0.1 + 0.2 == 0.3); System.out.println(0.1 + 0.2); } }Lösung anzeigen
Ausgabe:
false 0.30000000000000004
0.1 und 0.2 sind im Binärsystem nicht exakt darstellbar. Die Summe weicht minimal von 0.3 ab. Für Geld und exakte Vergleiche: BigDecimal oder Vergleich mit Toleranz.
- Stream-Summe ★☆☆ Streams ✓ gelöst
Was gibt dieses Programm aus?
import java.util.stream.IntStream; public class Main { public static void main(String[] args) { int sum = IntStream.rangeClosed(1, 10) .filter(x -> x % 2 == 1) .map(x -> x * x) .sum(); System.out.println(sum); } }Lösung anzeigen
Ausgabe:
165
rangeClosed schließt die 10 ein. Ungerade Zahlen: 1, 3, 5, 7, 9. Quadrate: 1 + 9 + 25 + 49 + 81 = 165. (385 wäre die Summe aller Quadrate 1–10, 220 die der geraden.)
- char plus int ★★☆ Datentypen · Strings ✓ gelöst
Was gibt dieses Programm aus?
public class Main { public static void main(String[] args) { System.out.println('a' + 1); System.out.println("" + 'a' + 1); char c = 'a'; c += 1; System.out.println(c); } }Lösung anzeigen
Ausgabe:
98 a1 b
'a' + 1 ist eine int-Addition ('a' = 97). Mit "" vorne wird zur String-Verkettung. c += 1 enthält einen impliziten Cast zurück auf char, deshalb kommt 'b' heraus (c = c + 1 würde dagegen nicht kompilieren).
- Prä- und Post-Inkrement ★★☆ Operatoren ✓ gelöst
Was gibt dieses Programm aus?
public class Main { public static void main(String[] args) { int i = 5; int j = i++ + ++i; System.out.println(i + " " + j); } }Lösung anzeigen
Ausgabe:
7 12
i++ liefert 5 und erhöht i auf 6. ++i erhöht dann auf 7 und liefert 7. j = 5 + 7 = 12, i ist am Ende 7.
- Kurzschluss-Auswertung ★★☆ Operatoren · Logik ✓ gelöst
Was gibt dieses Programm aus?
public class Main { static int calls = 0; static boolean check(boolean v) { calls++; return v; } public static void main(String[] args) { if (check(false) && check(true)) { } System.out.println(calls); if (check(false) & check(true)) { } System.out.println(calls); } }Lösung anzeigen
Ausgabe:
1 3
&& wertet die rechte Seite nicht mehr aus, wenn links schon false steht (1 Aufruf). Das einfache & wertet immer beide Seiten aus (2 weitere Aufrufe, also 3).
- Integer-Überlauf ★★☆ Datentypen · Arithmetik ✓ gelöst
Was gibt dieses Programm aus?
public class Main { public static void main(String[] args) { System.out.println(Integer.MAX_VALUE + 1); System.out.println(Math.abs(Integer.MIN_VALUE)); System.out.println((byte) 200); } }Lösung anzeigen
Ausgabe:
-2147483648 -2147483648 -56
int läuft still über: MAX_VALUE + 1 springt auf MIN_VALUE. Math.abs(MIN_VALUE) ist nicht darstellbar und bleibt negativ – ein klassischer Bug. (byte) 200 schneidet auf 8 Bit: 200 - 256 = -56. Sichere Alternative: Math.addExact wirft bei Überlauf eine Exception.
- Rekursion ★★☆ Rekursion ✓ gelöst
Was gibt dieses Programm aus?
public class Main { static int f(int n) { if (n == 0) return 0; return n % 2 + 10 * f(n / 2); } public static void main(String[] args) { System.out.println(f(13)); } }Lösung anzeigen
Ausgabe:
1101
Die Funktion wandelt n in seine Binärdarstellung um und schreibt sie als Dezimalzahl: 13 = 8 + 4 + 1 = 1101. Die niedrigste Stelle (n % 2) landet ganz rechts, weil das rekursive Ergebnis mit 10 multipliziert wird.
- Labels mit break und continue ★★☆ Kontrollfluss ✓ gelöst
Was gibt dieses Programm aus?
public class Main { public static void main(String[] args) { int count = 0; outer: for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (j == 2) continue outer; if (i == 2) break outer; count++; } } System.out.println(count); } }Lösung anzeigen
Ausgabe:
4
Bei i = 0 und i = 1 zählen jeweils j = 0 und j = 1 (je 2), bei j = 2 geht es direkt zum nächsten i. Bei i = 2 bricht schon j = 0 die äußere Schleife ab. Ergebnis 2 + 2 = 4.
- list.remove: Index oder Objekt? ★★☆ Collections · Overloading ✓ gelöst
Was gibt dieses Programm aus?
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { List<Integer> list = new ArrayList<>(List.of(1, 2, 3)); list.remove(1); list.remove(Integer.valueOf(1)); System.out.println(list); } }Lösung anzeigen
Ausgabe:
[3]
remove(1) mit int-Literal ruft remove(int index) auf und entfernt das Element an Position 1, also die 2. remove(Integer.valueOf(1)) ruft remove(Object) auf und entfernt den Wert 1. Übrig bleibt [3].
- Integer-Cache ★★★ Autoboxing · Gleichheit ✓ gelöst
Was gibt dieses Programm aus?
public class Main { public static void main(String[] args) { Integer a = 127, b = 127; Integer c = 128, d = 128; System.out.println(a == b); System.out.println(c == d); System.out.println(c.equals(d)); } }Lösung anzeigen
Ausgabe:
true false true
Autoboxing nutzt Integer.valueOf, das Werte von -128 bis 127 zwischenspeichert. Darum zeigen a und b auf dasselbe Objekt, c und d auf zwei verschiedene. == vergleicht Referenzen, equals den Wert. Lehre: Wrapper-Objekte immer mit equals vergleichen.
- String-Pool ★★★ Strings · Gleichheit ✓ gelöst
Was gibt dieses Programm aus?
public class Main { public static void main(String[] args) { String s1 = "Java"; String s2 = "Java"; String s3 = new String("Java"); System.out.println(s1 == s2); System.out.println(s1 == s3); System.out.println(s1 == s3.intern()); } }Lösung anzeigen
Ausgabe:
true false true
Literale landen im String-Pool, s1 und s2 sind dasselbe Objekt. new String erzeugt immer ein neues Objekt. intern() liefert die Pool-Instanz zurück, also wieder dieselbe wie s1.
- return im finally ★★★ Exceptions · Kontrollfluss ✓ gelöst
Was gibt dieses Programm aus?
public class Main { static int test() { try { return 1; } finally { return 2; } } public static void main(String[] args) { System.out.println(test()); } }Lösung anzeigen
Ausgabe:
2
finally läuft immer, auch nach einem return im try. Ein return im finally überschreibt den ursprünglichen Rückgabewert (und würde sogar eine Exception verschlucken). Kompiliert mit Warnung, gilt als schlechter Stil.
- Overloading mit null ★★★ Overloading ✓ gelöst
Was gibt dieses Programm aus?
public class Main { static void m(Object o) { System.out.println("Object"); } static void m(String s) { System.out.println("String"); } public static void main(String[] args) { m(null); Object x = "Hallo"; m(x); } }Lösung anzeigen
Ausgabe:
String Object
Beim Overloading entscheidet der Compiler zur Übersetzungszeit anhand des statischen Typs. null passt zu beiden, gewählt wird die spezifischere Methode (String). x hat den statischen Typ Object, also wird m(Object) gewählt, auch wenn zur Laufzeit ein String drinsteckt.
- Feld-Verdeckung vs. Überschreiben ★★★ Vererbung · Polymorphie ✓ gelöst
Was gibt dieses Programm aus?
public class Main { public static void main(String[] args) { A a = new B(); System.out.println(a.name + a.getName()); } } class A { String name = "A"; String getName() { return name; } } class B extends A { String name = "B"; @Override String getName() { return name; } }Lösung anzeigen
Ausgabe:
AB
Felder sind nicht polymorph: a.name richtet sich nach dem statischen Typ A. Methoden werden dagegen zur Laufzeit dynamisch gebunden: getName() aus B liefert B.name.
- Statische Methoden verdecken ★★★ Vererbung · static ✓ gelöst
Was gibt dieses Programm aus?
public class Main { public static void main(String[] args) { Parent p = new Child(); System.out.println(p.hello() + " " + p.who()); } } class Parent { static String hello() { return "Parent"; } String who() { return "Parent"; } } class Child extends Parent { static String hello() { return "Child"; } String who() { return "Child"; } }Lösung anzeigen
Ausgabe:
Parent Child
Statische Methoden werden nicht überschrieben, sondern nur verdeckt (hiding). Der Aufruf über eine Referenz vom Typ Parent ruft Parent.hello(). who() ist eine Instanzmethode und wird dynamisch gebunden.
- HashSet ohne hashCode ★★★ Collections · equals/hashCode ✓ gelöst
Was gibt dieses Programm aus?
import java.util.HashSet; import java.util.Set; public class Main { public static void main(String[] args) { Set<Point> set = new HashSet<>(); set.add(new Point(1, 2)); set.add(new Point(1, 2)); System.out.println(set.size()); System.out.println(new Point(1, 2).equals(new Point(1, 2))); } } class Point { int x, y; Point(int x, int y) { this.x = x; this.y = y; } @Override public boolean equals(Object o) { if (!(o instanceof Point)) return false; Point p = (Point) o; return x == p.x && y == p.y; } }Lösung anzeigen
Ausgabe:
2 true
equals ist überschrieben, hashCode nicht. HashSet sucht zuerst über hashCode den Bucket, und zwei verschiedene Objekte haben (praktisch immer) verschiedene Standard-Hashcodes. equals wird dann gar nicht erst gefragt. Regel: equals und hashCode immer gemeinsam überschreiben (oder record verwenden).
- Ternärer Operator und Unboxing ★★★ Autoboxing · Exceptions ✓ gelöst
Was gibt dieses Programm aus?
public class Main { public static void main(String[] args) { Integer i = null; try { Integer r = true ? i : 0; System.out.println(r); } catch (Exception e) { System.out.println(e.getClass().getSimpleName()); } } }Lösung anzeigen
Ausgabe:
NullPointerException
Weil ein Zweig int ist (0), wird der Ausdruck als int typisiert und i wird automatisch ausgepackt (i.intValue()). Auf null knallt das, obwohl das Ergebnis wieder einem Integer zugewiesen wird. Ein sehr realer Bug in Produktionscode.