Streng typisiert und objektorientiert, überall im Einsatz
Ausführen: Ab Java 11 genügt für kleine Programme java Hallo.java (ohne Extra-Schritt). Klassisch: Datei Hallo.java speichern, mit javac Hallo.java übersetzen und mit java Hallo starten. Ein JDK muss installiert sein (z. B. Temurin oder OpenJDK).
java Datei.java kleine Programme direktjava -version # zeigt die Laufzeitumgebung
javac -version # zeigt den Compiler (nur im JDK)public static void main(String[] args) ist der StartpunktSystem.out.println gibt mit Zeilenumbruch aus, printf formatiertGross, Methoden/Variablen klein, Konstanten GROSSpublic class Hallo {
public static void main(String[] args) {
System.out.println("Hallo, Welt!");
System.out.print("Ohne Zeilenumbruch, ");
System.out.println("dann geht es weiter.");
System.out.printf("Zahl: %d, Kommazahl: %.2f, Text: %s%n", 42, 3.14159, "Java");
}
}byte, short, int, long, float, double, char, boolean; String ist eine Klasseint und double sind die Standardtypenvar lässt den Compiler den Typ erkennen; final macht eine Variable unveränderlich(int) x schneidet ab; 7 / 2 ist 3.equals() vergleichen; Geld mit BigDecimalpublic class Typen {
public static void main(String[] args) {
int alter = 17;
long einwohner = 83_000_000L; // Unterstriche machen Zahlen lesbar
double preis = 19.99;
char note = 'A';
boolean volljaehrig = alter >= 18;
String name = "Mia";
System.out.println(name + " ist " + alter + ", Note " + note + ", volljährig: " + volljaehrig);
System.out.println(einwohner + " / " + preis);
System.out.println(Integer.MAX_VALUE + " " + Integer.MIN_VALUE + " " + Long.MAX_VALUE);
System.out.println(Double.MAX_VALUE);
}
}/ bei int schneidet ab, % liefert den Rest== für primitive Typen; Objekte mit .equals()&& und || werten kurz ausbedingung ? a : b ist die Kurzform von if/elseinstanceof mit Pattern Matching prüft und benennt in einem SchrittMath.addExact meldet Überläufepublic class Rechnen {
public static void main(String[] args) {
int a = 17, b = 5;
System.out.println(a + " + " + b + " = " + (a + b));
System.out.println(a / b + " Rest " + a % b);
System.out.println((double) a / b);
int i = 5;
System.out.println(i++ + " " + i); // erst benutzen, dann erhöhen
System.out.println(++i + " " + i); // erst erhöhen, dann benutzen
i += 10; i *= 2;
System.out.println(i);
System.out.println(Math.pow(2, 10) + " " + Math.sqrt(144) + " " + Math.abs(-7) + " " + Math.max(3, 9));
System.out.println(Math.round(2.5) + " " + Math.round(-2.5) + " " + Math.floor(-2.5) + " " + Math.ceil(2.1));
}
}.equals(), nie mit ==split, substring, replace, contains, strip, repeat, join im AlltagStringBuilder für viele Änderungen; Textblöcke """ für mehrzeiligen TextString.formatted(...) und printf formatierenCollator sortiert sprachrichtigpublic class Texte {
public static void main(String[] args) {
String s = "Java macht Spaß";
System.out.println(s.length());
System.out.println(s.charAt(0) + " " + s.indexOf("macht") + " " + s.indexOf("x"));
System.out.println(s.toUpperCase() + " | " + s.toLowerCase());
System.out.println(s.substring(5) + " | " + s.substring(0, 4));
System.out.println(s.replace("a", "4") + " | " + s.contains("Spaß") + " | " + s.startsWith("Java"));
System.out.println(" Leerraum ".trim() + "|" + " Leerraum ".strip() + "|");
System.out.println(String.join(", ", "a", "b", "c") + " " + "ab".repeat(3) + " " + "".isEmpty() + " " + " ".isBlank());
}
}if-Bedingungen müssen boolean sein; immer { } setzenswitch braucht break; der moderne Ausdruck mit -> nichtswitch kann einen Wert liefern, mit yield in Blöckenswitchpublic class Note {
public static void main(String[] args) {
int punkte = 73;
if (punkte >= 90) {
System.out.println("sehr gut");
} else if (punkte >= 75) {
System.out.println("gut");
} else if (punkte >= 50) {
System.out.println("bestanden");
} else {
System.out.println("nicht bestanden");
}
}
}for für feste Anzahl, while für Bedingungen, do-while läuft mindestens einmalfor (Typ x : sammlung) ist die einfachste Art, über Arrays und Listen zu laufenbreak beendet, continue überspringt; Marken verlassen mehrere Schleifenpublic class Zaehlen {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
System.out.print(i + " ");
}
System.out.println();
int summe = 0;
for (int i = 1; i <= 100; i++) summe += i;
System.out.println(summe);
for (int i = 10; i > 0; i -= 3) System.out.print(i + " ");
System.out.println();
}
}static Rückgabetyp name(Parameter) { ... return wert; }int... zahlen; Rekursion braucht eine Abbruchbedingungpublic class Methoden {
static int addiere(int a, int b) {
return a + b;
}
static void gruss(String name) {
System.out.println("Hallo " + name + "!");
}
static boolean istGerade(int n) {
return n % 2 == 0;
}
public static void main(String[] args) {
System.out.println(addiere(3, 4));
gruss("Mia");
System.out.println(istGerade(10) + " " + istGerade(7));
int ergebnis = addiere(addiere(1, 2), 3);
System.out.println(ergebnis);
}
}int[] a = new int[5] oder {1, 2, 3}; Index ab 0; a.length ist die GrößeArrayIndexOutOfBoundsExceptionArrays.toString, sort, copyOf, fill, equals sind die wichtigsten Helferb = a kopiert nur den Verweis, clone() oder copyOf kopieren die Datenint[][] mimport java.util.Arrays;
public class Felder {
public static void main(String[] args) {
int[] zahlen = {5, 3, 9, 1, 7}; // direkt mit Werten
String[] namen = new String[3]; // 3 Plätze, anfangs null
double[] preise = new double[4]; // anfangs 0.0
namen[0] = "Mia";
System.out.println(zahlen[0] + " " + zahlen[zahlen.length - 1] + " " + zahlen.length);
System.out.println(Arrays.toString(namen) + " " + Arrays.toString(preise));
zahlen[1] = 30;
System.out.println(Arrays.toString(zahlen));
try {
System.out.println(zahlen[5]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Fehler: " + e.getMessage());
}
}
}List<String>, Map<String, Integer>ArrayList, HashSet, HashMap sind die Standardwahl; Tree... sortiert, LinkedHash... merkt die ReihenfolgeList.of, Set.of, Map.of sind unveränderlichmerge, computeIfAbsent, getOrDefault machen Maps bequemArrayDeque für Stapel und SchlangenComparator.comparing(...)import java.util.*;
public class Listen {
public static void main(String[] args) {
List<String> namen = new ArrayList<>();
namen.add("Mia");
namen.add("Tom");
namen.add(1, "Zoe"); // an Index einfügen
System.out.println(namen + " " + namen.size());
System.out.println(namen.get(0) + " " + namen.indexOf("Tom") + " " + namen.contains("Max"));
namen.remove("Zoe");
namen.set(0, "Mia2");
System.out.println(namen);
for (String n : namen) System.out.print(n + ";");
System.out.println();
List<Integer> zahlen = new ArrayList<>(List.of(5, 3, 9, 1));
Collections.sort(zahlen);
System.out.println(zahlen + " max " + Collections.max(zahlen) + " " + Collections.frequency(zahlen, 3));
zahlen.removeIf(z -> z > 4);
zahlen.replaceAll(z -> z * 10);
System.out.println(zahlen);
}
}new ruft den Konstruktorprivate, Zugriff über Methodenthis ist das aktuelle Objekt; static gehört zur Klasseequals und hashCode immer gemeinsam überschreibennull vermeiden, Optional nutzenpublic class Hund {
// Felder (Zustand)
private String name;
private int alter;
// Konstruktor: legt das Objekt an
public Hund(String name, int alter) {
this.name = name;
this.alter = alter;
}
// Methoden (Verhalten)
public String bellen() {
return name + " sagt: Wuff!";
}
public void geburtstag() {
alter++;
}
// Getter
public String getName() { return name; }
public int getAlter() { return alter; }
@Override
public String toString() {
return "Hund[" + name + ", " + alter + "]";
}
public static void main(String[] args) {
Hund rex = new Hund("Rex", 3);
Hund mimi = new Hund("Mimi", 5);
rex.geburtstag();
System.out.println(rex.bellen() + " " + rex.getAlter());
System.out.println(rex + " " + mimi);
}
}class B extends A erbt; super(...) ruft den Elternkonstruktor, @Override überschreibt bewusstabstract für Vorlagen; interface für Verträge und Fähigkeiten (mehrere möglich)Objectpublic class Tiere {
static class Tier {
protected String name;
Tier(String name) { this.name = name; }
String laut() { return "..."; }
String vorstellen() { return name + " macht " + laut(); }
}
static class Hund extends Tier {
Hund(String name) { super(name); } // Konstruktor der Oberklasse
@Override String laut() { return "Wuff"; }
}
static class Katze extends Tier {
Katze(String name) { super(name); }
@Override String laut() { return "Miau"; }
@Override String vorstellen() { return super.vorstellen() + " (und schnurrt)"; }
}
public static void main(String[] args) {
Tier[] tiere = { new Hund("Rex"), new Katze("Mimi"), new Tier("Etwas") };
for (Tier t : tiere) System.out.println(t.vorstellen()); // Polymorphie
}
}record Punkt(int x, int y) {} erzeugt Konstruktor, Getter, equals, hashCode, toStringsealed begrenzt erlaubte Untertypen; switch prüft Vollständigkeitpublic class Aufnahme {
record Person(String name, int alter) {
Person { // kompakter Konstruktor: Prüfung
if (alter < 0) throw new IllegalArgumentException("Alter < 0");
}
String gruss() { return "Hallo, ich bin " + name; }
static Person kind(String name) { return new Person(name, 0); }
}
public static void main(String[] args) {
Person mia = new Person("Mia", 17);
System.out.println(mia); // toString automatisch
System.out.println(mia.name() + " " + mia.alter() + " " + mia.gruss());
System.out.println(mia.equals(new Person("Mia", 17)) + " " + Person.kind("Tom"));
try { new Person("X", -1); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); }
}
}try { } catch (Typ e) { } finally { }; throw new ... löst aus, throws meldet anRuntimeExceptions nichtcatch-Blöcke vor allgemeinentry-with-resources schließt Ressourcen automatischException oder RuntimeException; Ursache mitgebenpublic class Fangen {
public static void main(String[] args) {
try {
System.out.println("vorher");
int x = Integer.parseInt("abc");
System.out.println("wird nie erreicht " + x);
} catch (NumberFormatException e) {
System.out.println("Ungültige Zahl: " + e.getMessage());
} finally {
System.out.println("läuft immer");
}
System.out.println("Programm läuft weiter");
}
}class Box<T>, <T> void f(T x)T extends Comparable<T> schränkt Typparameter ein? extends T zum Lesen, ? super T zum Schreiben (PECS)List ohne <>)import java.util.*;
public class Ohne {
@SuppressWarnings({"rawtypes", "unchecked"})
public static void main(String[] args) {
List liste = new ArrayList(); // "raw type": nicht tun!
liste.add("Text");
liste.add(42);
try {
String s = (String) liste.get(1); // ClassCastException erst zur Laufzeit
} catch (ClassCastException e) {
System.out.println("Laufzeitfehler: " + e.getMessage().substring(0, 40));
}
}
}(a, b) -> a + b und Methodenreferenzen String::length ersetzen kleine KlassenFunction, Predicate, Consumer, Supplierfilter/map/sorted → Endoperation (collect, count, reduce)Collectors.groupingBy, partitioningBy, toMap, joining für Auswertungenimport java.util.*;
import java.util.function.*;
public class Lambdas {
public static void main(String[] args) {
Function<Integer, Integer> quadrat = x -> x * x;
BiFunction<Integer, Integer, Integer> plus = (a, b) -> a + b;
Predicate<String> leer = s -> s.isEmpty();
Supplier<String> lieferant = () -> "Wert";
Consumer<String> ausgabe = s -> System.out.println("> " + s);
UnaryOperator<String> gross = String::toUpperCase; // Methodenreferenz
System.out.println(quadrat.apply(7) + " " + plus.apply(3, 4) + " " + leer.test("") + " " + lieferant.get());
ausgabe.accept(gross.apply("hallo"));
System.out.println(quadrat.andThen(x -> x + 1).apply(5)); // verketten
System.out.println(leer.negate().test("x"));
List<String> namen = new ArrayList<>(List.of("Zoe", "Anna", "Tom"));
namen.sort((a, b) -> a.length() - b.length());
namen.forEach(n -> System.out.print(n + " "));
System.out.println();
}
}Path und Files (readString, writeString, readAllLines, lines, walk)IOException (checked)BufferedReader, Files.lines), Ressourcen mit try-with-resources schließenPath.of(...), resolve, normalize statt Zeichenketten für PfadeScanner liest Eingaben; für JSON Jackson oder Gsonimport java.io.IOException;
import java.nio.file.*;
import java.util.*;
public class Dateien {
public static void main(String[] args) throws IOException {
Path ordner = Files.createTempDirectory("kurs");
Path datei = ordner.resolve("notiz.txt"); // Pfad zusammensetzen
Files.writeString(datei, "Zeile 1\nZeile 2\n");
Files.writeString(datei, "Zeile 3\n", StandardOpenOption.APPEND);
String inhalt = Files.readString(datei);
List<String> zeilen = Files.readAllLines(datei);
System.out.println(zeilen + " " + inhalt.length());
System.out.println(Files.exists(datei) + " " + Files.size(datei) + " " + datei.getFileName());
Path kopie = ordner.resolve("kopie.txt");
Files.copy(datei, kopie);
try (var strom = Files.list(ordner)) {
strom.map(p -> p.getFileName().toString()).sorted().forEach(System.out::println);
}
Files.delete(kopie);
Files.delete(datei);
Files.delete(ordner);
System.out.println(Files.exists(ordner));
}
}java.time: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, InstantplusDays(...) liefert ein neuesChronoUnit.DAYS.between, Period, Duration für ZeitspannenDateTimeFormatter.ofPattern("dd.MM.yyyy") zum Formatieren und EinlesenInstant/UTC speichern; Clock macht Code testbarimport java.time.*;
import java.time.format.*;
public class Zeit {
public static void main(String[] args) {
LocalDate d = LocalDate.of(2025, 3, 8);
System.out.println(d + " " + d.getDayOfWeek() + " " + d.getMonth() + " " + d.getDayOfYear() + " " + d.isLeapYear());
LocalDate morgen = d.plusDays(1);
LocalDate in3Monaten = d.plusMonths(3);
System.out.println(morgen + " " + in3Monaten + " " + d.minusWeeks(2) + " " + d.withDayOfMonth(1));
LocalDateTime dt = LocalDateTime.of(2025, 12, 24, 18, 30);
System.out.println(dt + " " + dt.toLocalTime() + " " + dt.getHour());
System.out.println(d.isBefore(LocalDate.of(2025, 12, 24)) + " " + d.equals(LocalDate.parse("2025-03-08")));
}
}Thread, Runnable, start(), join() sind die Grundlage; besser sind Pools (ExecutorService)synchronized, Atomic*, ConcurrentHashMapFuture und CompletableFuture liefern Ergebnisse asynchronpublic class Faeden {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try { Thread.sleep(100); } catch (InterruptedException e) { }
System.out.println("t1 fertig");
});
Thread t2 = new Thread(() -> System.out.println("t2 fertig"));
t1.start();
t2.start();
t1.join(); // warten, bis t1 beendet ist
t2.join();
System.out.println("alle fertig");
}
}import holt Klassen aus anderen Paketensrc/main und src/test)@Test, assertEquals, assertThrowssrc/main/java/de/meinefirma/shop/Warenkorb.java
package de.meinefirma.shop;
import java.util.List;
import de.meinefirma.shop.modell.Artikel;
public class Warenkorb { ... }.equals() vergleichen; null mit Optional oder Standardwerten entschärfenremoveIf)BigDecimal; long-Rechnungen mit L-LiteralenSystem.out, Eingaben prüfen, Abhängigkeiten pflegenpublic class Fehler1 {
public static void main(String[] args) {
String eingabe = new String("ja");
System.out.println((eingabe == "ja") + " " + eingabe.equals("ja"));
System.out.println("ja".equals(eingabe)); // sicher gegen null auf der linken Seite
}
}// Klasse, Konstruktor, Methode
public class Person {
private final String name;
public Person(String name) { this.name = name; }
public String getName() { return name; }
}
// Interface, Record, Enum, sealed
interface Form { double flaeche(); }
record Punkt(int x, int y) {}
enum Tag { MO, DI, MI }
sealed interface S permits A, B {}
// Generics
<T extends Comparable<T>> T max(List<T> l) { ... }
// Lambda und Methodenreferenz
Function<Integer, Integer> f = x -> x * 2;
list.forEach(System.out::println);
// Ausnahmen
try { ... } catch (IOException | RuntimeException e) { ... } finally { ... }
try (var r = Files.newBufferedReader(p)) { ... }
// Schleifen
for (int i = 0; i < n; i++) { }
for (var x : liste) { }
while (bedingung) { }
// switch-Ausdruck
String s = switch (tag) { case MO, DI -> "früh"; default -> "spät"; };