← Alle LernbereicheFIAE · LF 5, 11a und 12a

Java: Anwendungen entwickeln

Mit Java Programme schreiben, Daten verarbeiten, Klassen entwerfen, Fehler behandeln und Ergebnisse durch Tests absichern.

01

Quellcode, Compiler und JVM

Java-Quelltext wird gewöhnlich mit javac zu Bytecode in .class-Dateien übersetzt. Die Java Virtual Machine führt diesen Bytecode aus; sie benötigt eine passende Laufzeitumgebung. Ein JDK enthält zusätzlich Entwicklungswerkzeuge wie den Compiler. Ein Syntaxfehler verhindert die Übersetzung, ein Laufzeitfehler tritt beim Ausführen auf und ein Logikfehler kann trotz erfolgreicher Ausführung ein falsches Ergebnis liefern. Die Werkstatt verwendet Java 21 und die Einstiegsklasse Main.

public class Main {
  public static void main(String[] args) {
    System.out.println("Hallo FISIBase");
  }
}
02

Variablen, Typen und sichere Zahlen

Java prüft Typen statisch. int und long speichern ganze Zahlen mit begrenztem Wertebereich; double verwendet binäre Gleitkommazahlen. boolean enthält true oder false. String ist ein Referenztyp für Zeichenketten. Ein final-Verweis kann nicht neu zugewiesen werden, macht aber ein referenziertes veränderbares Objekt nicht automatisch unveränderlich. Rechne Geld möglichst in ganzen Cent oder mit passend eingesetztem BigDecimal. Ganzzahldivision schneidet Richtung null ab: 7 / 2 ergibt 3.

int anzahl = 7;
long cent = 1299L;
double anteil = anzahl / 2.0;
boolean freigegeben = anzahl > 0;
03

Vergleiche und Kontrollfluss

if/else wählt anhand eines boolean-Ausdrucks einen Weg. && und || werten kurzschließend aus: Der zweite Operand wird nur ausgeführt, wenn er benötigt wird. Verwende bei String-Inhalten equals statt ==, denn == vergleicht Referenzen. Prüfe null vor dem Aufruf einer Instanzmethode oder nutze Objects.equals. Formuliere Grenzwerte aus der Anforderung: Eine Freigabe ab 18 benötigt >= 18, nicht > 18.

String status = "offen";
if ("offen".equals(status)) {
  System.out.println("bearbeiten");
}
04

Schleifen und Arrays

for, while und do/while unterscheiden sich bei Aufbau und Prüfzeitpunkt. Arrays besitzen eine feste Länge und nullbasierte Indizes. Der letzte gültige Index ist length - 1. Eine Schleife mit i <= array.length greift am Ende außerhalb des Arrays zu. Initialisiere Summen mit 0 und Minima bei nicht leeren Eingaben mit einem tatsächlichen ersten Wert statt pauschal mit 0. Leere Eingaben und Abbruchbedingungen brauchen ausdrückliche Regeln.

int[] werte = {4, 7, 2};
int summe = 0;
for (int wert : werte) summe += wert;
System.out.println(summe);
05

Methoden und Verantwortlichkeiten

Eine Methode besitzt Namen, Parameter und gegebenenfalls Rückgabewert. Trenne Eingabe/Ausgabe von der fachlichen Berechnung, damit die Berechnung unabhängig getestet werden kann. static-Methoden gehören zur Klasse; Instanzmethoden arbeiten über ein Objekt. Java übergibt Argumentwerte: Bei Referenzen wird der Referenzwert kopiert. Die Methode kann ein veränderbares Objekt beeinflussen, aber das Neuzuweisen ihres Parameters ersetzt nicht die Variable des Aufrufers.

static int addiere(int a, int b) {
  return a + b;
}
06

Klassen, Konstruktoren und Kapselung

Eine Klasse beschreibt Zustand und Verhalten; ein Konstruktor stellt einen gültigen Anfangszustand her. private schützt Implementierungsdetails. Eine Setter-Methode ist nur dann sinnvoll, wenn sie die fachlichen Regeln erhält. Verhindere etwa negative Minutenwerte schon am Eingang. Ein UML-Klassendiagramm zeigt Sichtbarkeit, Attribute und Operationen; es ersetzt die konkrete Implementierung und ihre Tests nicht.

class Ticket {
  private int minuten;
  Ticket(int minuten) {
    if (minuten < 0) throw new IllegalArgumentException("Minuten müssen >= 0 sein");
    this.minuten = minuten;
  }
  int minuten() { return minuten; }
}
07

Interfaces, Vererbung und Komposition

Ein Interface beschreibt einen Vertrag, den unterschiedliche Implementierungen erfüllen können. Polymorphie ermöglicht den Aufruf über diesen gemeinsamen Vertrag. Vererbung soll eine passende ist-ein-Beziehung ausdrücken; Komposition kombiniert zusammenarbeitende Objekte und ist oft flexibler. @Override lässt den Compiler prüfen, ob eine Methode tatsächlich überschreibt. Ein Methodenname allein stellt keine fachliche Austauschbarkeit sicher.

interface Benachrichtigung {
  String text();
}
class TicketHinweis implements Benachrichtigung {
  @Override public String text() { return "Neues Ticket"; }
}
08

Collections und Generics

List hält geordnete Elemente, Set eindeutige Elemente nach der jeweiligen Gleichheitsregel und Map Zuordnungen zwischen Schlüsseln und Werten. Generics wie List<String> machen viele Typfehler schon beim Übersetzen sichtbar. Eine HashMap garantiert keine bestimmte Iterationsreihenfolge. LinkedHashMap kann die Einfügereihenfolge erhalten. Prüfe, ob null-Werte, fehlende Schlüssel und leere Listen im konkreten Vertrag erlaubt sind. Für eigene Schlüssel müssen equals und hashCode zusammenpassen.

09

Ausnahmen und Ressourcen

Behandle erwartete Fehler dort, wo eine sinnvolle Entscheidung möglich ist. Fange nicht pauschal jede Ausnahme und melde anschließend trotzdem Erfolg. Checked Exceptions werden vom Compiler auf Deklaration oder Behandlung geprüft; RuntimeExceptions benötigen keine solche Deklaration. try-with-resources schließt AutoCloseable-Ressourcen auch beim Verlassen durch einen Fehler. Vertrauliche Inhalte gehören nicht in Fehlermeldungen.

try {
  int id = Integer.parseInt("12abc");
  System.out.println(id);
} catch (NumberFormatException error) {
  System.out.println("ungültige ID");
}
10

Dateien, SQL und Schnittstellen

Lies Texte mit vereinbarter Zeichencodierung. Trenne Dateneinlesen, Validierung, Mapping und Speicherung. PreparedStatement bindet Werte einer SQL-Abfrage als Parameter; dynamische Tabellen- oder Spaltennamen brauchen dagegen eine kontrollierte Auswahl. HTTPS und HTTP-Statusprüfung sind zusätzliche Ebenen. Unsere Codewerkstatt hat kein Netzwerk und keine Verbindung zur Kontodatenbank; die Übungen verwenden ausschließlich die jeweils bereitgestellte Standardeingabe.

11

Tests und Fehlersuche

Leite erwartete Ergebnisse aus der Anforderung ab. Teste Normalfälle, leere Eingaben, negative Werte soweit erlaubt, Duplikate und Werte an Grenzen. Eine bestandene Beispielausgabe bestätigt noch keine allgemeine Korrektheit. Beobachte Variablen an sinnvollen Stellen; entferne Debugausgaben wieder aus dem vereinbarten Ausgabeformat. JUnit ist ein verbreitetes Werkzeug für Java-Tests; die Werkstatt prüft Programme mit mehreren separaten Eingaben und erwartet genau die vereinbarte Ausgabe.

12

Praxis: Ticketbericht entwickeln

Entwirf einen kleinen Bericht mit Eingabeformat, fachlichen Regeln und definiertem Ausgabeformat. Implementiere das Einlesen, validiere IDs und Status und trenne die Berechnung von der Ausgabe. Begründe Datenstrukturen und Fehlerbehandlung. Teste insbesondere eine leere Liste, gleich große Maximalwerte und unbekannte Statusangaben. Dokumentiere Annahmen und erkläre, wie das Programm später an eine Datenquelle angeschlossen werden könnte. Starte dafür mit den schrittweise anspruchsvolleren Java-Aufgaben.

Wissen anwenden

Prüfe die Grundlagen in einer kurzen Übung.

Zur Übung ↗