Von Nova Trent, Junior Entwicklerin bei Java Fleet Systems Consulting

Schwierigkeit: 🟢 Einsteiger
Lesezeit: 30–35 Minuten
Voraussetzungen: Tag 1–2 abgeschlossen (Klassen, Objekte, Attribute, Methoden)


📋 Kursübersicht: Java OOP in 10 Tagen

TagThemaStatus
1OOP-Konzepte & erste Klasse✅ Abgeschlossen
2Attribute & Methoden✅ Abgeschlossen
→ 3Datenkapselung & Sichtbarkeit📍 Du bist hier
4Konstruktoren
5Konstanten & Static🔴 KOPFNUSS
6Vererbung – Grundlagen
7Vererbung – Polymorphie & Abstrakte Klassen
8Typumwandlung & instanceof
9Interfaces & Enumerationen
10Ausnahmebehandlung🔴 KOPFNUSS

Voraussetzung: Tag 1–2 abgeschlossen
Folgekurs: Erweiterte Techniken (Kurs 3)


🔄 Kurz-Wiederholung: Challenge von Tag 2

Die Aufgabe war: Erweitere die Auto-Klasse um kilometerstand, überladene fahren()-Methoden und einen Getter.

Lösung:

public class Auto {
    String farbe;
    int ps;
    int kilometerstand = 0;
    
    // Überladene Methoden
    void fahren(int km) {
        kilometerstand += km;
        System.out.println("Gefahren: " + km + " km. Stand: " + kilometerstand);
    }
    
    void fahren(int km, String ziel) {
        System.out.println("Fahre nach " + ziel + "...");
        fahren(km);  // Ruft die andere Version auf
    }
    
    // Getter
    int getKilometerstand() {
        return kilometerstand;
    }
    
    // Tanken
    void tanken(double liter) {
        System.out.println("Getankt: " + liter + " Liter");
    }
}

Hast du’s hinbekommen? Super! Aber dir ist vielleicht aufgefallen: Jeder kann auto.kilometerstand = -5000 setzen. Das ist ein Problem — und genau darum geht’s heute!


⚡ Das Wichtigste in 30 Sekunden

Dein Problem: Jeder kann deine Attribute direkt ändern — auch mit unsinnigen Werten wie -500 PS oder null.

Die Lösung: Mach Attribute private und kontrolliere den Zugriff über Getter/Setter.

Heute lernst du:

  • ✅ Die 4 Sichtbarkeitsmodifier: public, private, protected, (default)
  • ✅ Warum Kapselung so wichtig ist
  • ✅ Getter und Setter mit Validierung
  • ✅ Die JavaBeans-Konvention

Für wen ist dieser Artikel?

  • 🌱 OOP-Neulinge: Du lernst Kapselung von Grund auf
  • 🌿 OOP-Umsteiger: Du siehst Java vs. C#/C++ Unterschiede
  • 🌳 Profis: Im Bonus: Immutable Objects, Records, Defensive Copies

Zeit-Investment: 30–35 Minuten


👋 Nova: „Das hätte ich früher wissen sollen!“

Hey! 👋

Nova wieder.

Heute wird’s richtig wichtig. Ehrlich? Das hier hätte ich VOR meinem ersten Praktikum lernen sollen.

Stell dir vor: Du baust eine Banking-App. Ein Konto-Objekt mit kontostand. Und dann macht irgendein Code irgendwo konto.kontostand = -999999. Boom. Dein System ist kaputt.

„Aber wer würde sowas machen?“ — Niemand absichtlich. Aber Bugs passieren. Typos passieren. Und plötzlich ist der Kontostand negativ.

Kapselung verhindert das. Du sagst: „Hey, an meine Daten kommt nur, wer durch MEINE Methoden geht.“ Und in diesen Methoden kannst du prüfen, validieren, loggen — was auch immer du willst.

Real talk: Als Elyndra mir das zum ersten Mal erklärt hat, dachte ich „Ist das nicht Overkill?“ Heute weiß ich: Nope. Das ist der Unterschied zwischen Hobby-Code und professionellem Code.

Let’s go! 🚀


🟢 GRUNDLAGEN

Das Problem: Unkontrollierter Zugriff

Schau dir das an:

public class Auto {
    String farbe;
    int ps;
    int kilometerstand;
}
Auto auto = new Auto();
auto.farbe = "Rot";
auto.ps = 150;
auto.kilometerstand = 50000;

// Aber auch das geht...
auto.ps = -500;           // 😱 Negative PS?!
auto.kilometerstand = -1; // 😱 Negativer Kilometerstand?!
auto.farbe = null;        // 😱 Keine Farbe?!

Das Problem:

  • Jeder kann jedes Attribut direkt ändern
  • Keine Validierung möglich
  • Ungültige Zustände sind möglich
  • Debugging wird zum Albtraum („Wer hat den Wert geändert?!“)

Die Lösung: Kapselung (Encapsulation)

Kapselung bedeutet:

  1. Verstecke die internen Daten (private)
  2. Kontrolliere den Zugriff über Methoden (Getter/Setter)
Datenkapselung

Abbildung 1: Ohne Kapselung kann jeder direkt auf Daten zugreifen. Mit Kapselung läuft alles über kontrollierte Methoden.

Die 4 Sichtbarkeitsmodifier

Java hat vier Stufen der Sichtbarkeit:

Abbildung 2: Von public (überall sichtbar) bis private (nur in der eigenen Klasse).

Im Detail:

ModifierSichtbar in…Verwendung
publicÜberallAPIs, öffentliche Methoden
protectedKlasse + Package + SubklassenVererbung
(kein Modifier)Klasse + PackagePackage-interne Helfer
privateNur eigene KlasseStandard für Attribute!

private — Der Standard für Attribute

Regel: Mach Attribute IMMER private!

public class Auto {
    private String farbe;      // ✅ private
    private int ps;            // ✅ private
    private int kilometerstand; // ✅ private
}

Jetzt kann niemand mehr direkt darauf zugreifen:

Auto auto = new Auto();
auto.farbe = "Rot";  // ❌ Compilerfehler! farbe has private access

„Aber wie setze ich dann die Farbe?“ — Mit Getter und Setter!

Getter — Werte lesen

Ein Getter ist eine Methode, die den Wert eines privaten Attributs zurückgibt:

public class Auto {
    private String farbe;
    
    // GETTER
    public String getFarbe() {
        return farbe;
    }
}
Auto auto = new Auto();
String f = auto.getFarbe();  // ✅ Funktioniert!

Setter — Werte setzen (mit Validierung!)

Ein Setter ist eine Methode, die den Wert eines privaten Attributs setzt:

public class Auto {
    private int ps;
    
    // SETTER mit Validierung
    public void setPs(int ps) {
        if (ps < 0) {
            throw new IllegalArgumentException("PS darf nicht negativ sein!");
        }
        if (ps > 2000) {
            throw new IllegalArgumentException("PS unrealistisch hoch!");
        }
        this.ps = ps;
    }
}
Auto auto = new Auto();
auto.setPs(150);   // ✅ Funktioniert
auto.setPs(-50);   // ❌ Exception! "PS darf nicht negativ sein!"

Abbildung 3: Getter lesen Werte, Setter können validieren und ungültige Werte ablehnen.

Die JavaBeans-Konvention

Java hat Namenskonventionen für Getter und Setter:

AttributGetterSetter
String farbegetFarbe()setFarbe(String farbe)
int psgetPs()setPs(int ps)
boolean aktivisAktiv()setAktiv(boolean aktiv)

Beachte: Bei boolean heißt der Getter is...() statt get...()!

public class Auto {
    private boolean motorLaeuft;
    
    public boolean isMotorLaeuft() {  // ✅ isXxx für boolean
        return motorLaeuft;
    }
    
    public void setMotorLaeuft(boolean motorLaeuft) {
        this.motorLaeuft = motorLaeuft;
    }
}

Vollständiges Beispiel

Hier eine komplett gekapselte Auto-Klasse:

public class Auto {
    // Private Attribute
    private String farbe;
    private int ps;
    private int kilometerstand;
    private boolean motorLaeuft;
    
    // === GETTER ===
    
    public String getFarbe() {
        return farbe;
    }
    
    public int getPs() {
        return ps;
    }
    
    public int getKilometerstand() {
        return kilometerstand;
    }
    
    public boolean isMotorLaeuft() {
        return motorLaeuft;
    }
    
    // === SETTER mit Validierung ===
    
    public void setFarbe(String farbe) {
        if (farbe == null || farbe.isBlank()) {
            throw new IllegalArgumentException("Farbe darf nicht leer sein!");
        }
        this.farbe = farbe;
    }
    
    public void setPs(int ps) {
        if (ps < 0 || ps > 2000) {
            throw new IllegalArgumentException("PS muss zwischen 0 und 2000 liegen!");
        }
        this.ps = ps;
    }
    
    // Kilometerstand: Nur erhöhen, nicht setzen!
    public void fahren(int km) {
        if (km < 0) {
            throw new IllegalArgumentException("Kilometer dürfen nicht negativ sein!");
        }
        this.kilometerstand += km;
    }
    
    // Motor: Starten und Stoppen
    public void starteMotor() {
        if (motorLaeuft) {
            System.out.println("Motor läuft bereits!");
            return;
        }
        motorLaeuft = true;
        System.out.println("Motor gestartet! 🚗");
    }
    
    public void stoppeMotor() {
        if (!motorLaeuft) {
            System.out.println("Motor ist bereits aus!");
            return;
        }
        motorLaeuft = false;
        System.out.println("Motor gestoppt.");
    }
}

Was haben wir erreicht?

  • farbe kann nicht null oder leer sein
  • ps muss zwischen 0 und 2000 liegen
  • kilometerstand kann nur erhöht werden (kein direkter Setter!)
  • motorLaeuft hat sinnvolle Start/Stopp-Logik

Wann brauche ich KEINEN Setter?

Manchmal willst du, dass ein Wert nur gelesen werden kann:

public class Bestellung {
    private final String bestellnummer;  // final = unveränderlich
    private double betrag;
    
    public Bestellung(String bestellnummer) {
        this.bestellnummer = bestellnummer;
    }
    
    // Nur Getter, KEIN Setter für bestellnummer!
    public String getBestellnummer() {
        return bestellnummer;
    }
    
    // Betrag kann geändert werden
    public double getBetrag() {
        return betrag;
    }
    
    public void setBetrag(double betrag) {
        this.betrag = betrag;
    }
}

Regel: Nicht jedes Attribut braucht einen Setter! Überlege: „Soll dieser Wert nach der Erstellung änderbar sein?“


🟡 PROFESSIONALS

Schon OOP-Erfahrung aus C#, C++, PHP? Hier sind die Java-Besonderheiten.

Für C#-Umsteiger: Keine Auto-Properties

In C# hast du elegante Auto-Properties:

// C# — Auto-Property
public class Auto {
    public string Farbe { get; set; }
    public int Ps { get; private set; }  // Nur intern setzbar
}

In Java musst du alles ausschreiben:

// Java — Manuell
public class Auto {
    private String farbe;
    private int ps;
    
    public String getFarbe() { return farbe; }
    public void setFarbe(String farbe) { this.farbe = farbe; }
    
    public int getPs() { return ps; }
    // Kein public Setter → nur intern änderbar
}

Tipp: Nutze Lombok (siehe Tag 2) für @Getter und @Setter!

Für C++-Umsteiger: Keine friend-Klassen

C++ hat friend:

// C++ — friend kann auf private zugreifen
class Auto {
    friend class Werkstatt;  // Werkstatt hat Zugriff auf private
private:
    int kilometerstand;
};

Java hat kein friend! Alternativen:

  • Package-private (default) Sichtbarkeit
  • Protected für Subklassen
  • Innere Klassen haben Zugriff auf private der äußeren Klasse

Für PHP-Umsteiger: Keine Magic Methods für Properties

PHP hat __get() und __set():

// PHP — Magic Methods
class Auto {
    private $farbe;
    
    public function __get($name) {
        return $this->$name;
    }
    
    public function __set($name, $value) {
        $this->$name = $value;
    }
}

$auto->farbe = "Rot";  // Ruft __set auf

Java hat keine Magic Methods! Du musst explizite Getter/Setter schreiben. Das ist verbos, aber auch expliziter und leichter zu debuggen.

Package-Private: Der vergessene Modifier

Wenn du keinen Modifier schreibst, ist es package-private (default):

package de.javafleet.model;

class HilfsKlasse {  // Kein public!
    int helferWert;  // Kein Modifier = package-private
}

Wann nutzen?

  • Für Hilfsklassen, die nur im eigenen Package gebraucht werden
  • Für interne APIs, die nicht nach außen sichtbar sein sollen
de.javafleet.model/
├── Auto.java          (public class)
├── AutoValidator.java (package-private, nur intern)
└── AutoHelper.java    (package-private, nur intern)

Lombok für Kapselung

Mit Lombok wird Kapselung trivial:

import lombok.Getter;
import lombok.Setter;

public class Auto {
    @Getter @Setter
    private String farbe;
    
    @Getter  // Nur Getter, kein Setter!
    private int kilometerstand;
    
    @Getter @Setter
    private int ps;
}

Mit Validierung (Lombok + manueller Setter):

import lombok.Getter;

public class Auto {
    @Getter
    private int ps;
    
    // Manueller Setter MIT Validierung
    public void setPs(int ps) {
        if (ps < 0) throw new IllegalArgumentException("PS ungültig!");
        this.ps = ps;
    }
}

🔵 BONUS

Für Wissbegierige: Immutable Objects, Records, Defensive Copies.

Immutable Objects — Unveränderliche Objekte

Manchmal willst du Objekte, die nach der Erstellung nie mehr geändert werden können:

public final class Punkt {
    private final int x;
    private final int y;
    
    public Punkt(int x, int y) {
        this.x = x;
        this.y = y;
    }
    
    public int getX() { return x; }
    public int getY() { return y; }
    
    // Keine Setter! Stattdessen: Neues Objekt erstellen
    public Punkt verschiebenUm(int dx, int dy) {
        return new Punkt(x + dx, y + dy);
    }
}

Vorteile:

  • Thread-safe (keine Race Conditions)
  • Einfacher zu verstehen
  • Gut für Value Objects (Geld, Koordinaten, etc.)

Java Records (ab Java 16)

Für einfache Datenklassen gibt es Records:

// Statt 50 Zeilen Boilerplate...
public record Auto(String farbe, int ps) {}

// Automatisch generiert:
// - Konstruktor
// - Getter (farbe() statt getFarbe())
// - equals(), hashCode(), toString()
Auto auto = new Auto("Rot", 150);
System.out.println(auto.farbe());  // Rot
System.out.println(auto);          // Auto[farbe=Rot, ps=150]

Aber: Records sind immutable! Keine Setter möglich.

Defensive Copies — Schutz vor Manipulation

Bei veränderlichen Objekten in Attributen:

public class Termin {
    private final Date datum;  // Date ist veränderlich!
    
    public Termin(Date datum) {
        // ❌ FALSCH: Speichert Referenz
        // this.datum = datum;
        
        // ✅ RICHTIG: Defensive Copy
        this.datum = new Date(datum.getTime());
    }
    
    public Date getDatum() {
        // ❌ FALSCH: Gibt Original zurück
        // return datum;
        
        // ✅ RICHTIG: Defensive Copy
        return new Date(datum.getTime());
    }
}

Warum? Ohne Defensive Copy kann der Aufrufer das interne Datum ändern:

Date d = new Date();
Termin t = new Termin(d);
d.setTime(0);  // Ändert auch t.datum ohne Defensive Copy!

💬 Real Talk

Tom fragt, Nova erklärt — Die Fragen, die sich jeder stellt.

Java Fleet Küche, 14:00 Uhr. Tom sitzt vor seinem Laptop, Nova kommt mit einem Smoothie rein.


Tom: Nova, ich hab eine Frage… Warum sollte ich mir die Mühe machen, Getter und Setter zu schreiben? Kann ich nicht einfach alles public lassen?

Nova: setzt sich Kannst du. Bis es knallt.

Tom: Was meinst du?

Nova: Stell dir vor: Du hast eine Konto-Klasse mit public double kontostand. Läuft super. Dann, drei Monate später, sagt der Chef: „Wir brauchen Logging für jede Kontostand-Änderung.“

Tom: Okay… und?

Nova: tippt auf sein Laptop Dann musst du JEDEN ORT finden, wo konto.kontostand = xyz steht. Und das durch einen Methodenaufruf ersetzen. Überall. In 50 Dateien vielleicht.

Tom: Oh…

Nova: Mit einem Setter hättest du EINE Stelle geändert. Logging rein, fertig. Alle Aufrufer nutzen automatisch den neuen Code.

Tom: Das ergibt Sinn. Aber ist das nicht Overkill für kleine Projekte?

Nova: zuckt mit den Schultern Kleine Projekte werden groß. Und die Gewohnheit früh zu lernen ist besser als später umzulernen. Außerdem: IDE generiert Getter/Setter in zwei Sekunden.

Tom: Stimmt… IntelliJ macht das ja automatisch. tippt Alt+Insert, oder?

Nova: Exakt. Oder Lombok, dann brauchst du nur @Getter @Setter schreiben.

Tom: Eine Sache noch: Wann protected und wann package-private?

Nova: protected wenn Subklassen Zugriff brauchen — auch aus anderen Packages. Package-private wenn du was nur innerhalb deines Packages teilen willst. Ehrlich? In 90% der Fälle brauchst du nur public für Methoden und private für Attribute.

Tom: Also: Attribute private, Methoden public?

Nova: Als Faustregel, ja. Abweichungen wenn nötig, aber start damit. 👍


✅ Checkpoint: Hast du es verstanden?

Quiz

Frage 1: Welche vier Sichtbarkeitsmodifier gibt es in Java?

Frage 2: Was ist der empfohlene Modifier für Attribute und warum?

Frage 3: Wie heißt der Getter für ein boolean-Attribut aktiv?

Frage 4: Was ist der Unterschied zwischen protected und package-private (default)?

Frage 5: Du siehst diesen Code:

public class Konto {
    public double kontostand;
}

Was ist das Problem und wie löst du es?


Mini-Challenge

Aufgabe: Erstelle eine gekapselte Bankkonto-Klasse:

  1. Private Attribute:
    • kontonummer (String) — nur lesbar, nicht änderbar nach Erstellung
    • kontostand (double) — startet bei 0
    • pin (String) — 4 Ziffern, nur intern zugreifbar
  2. Methoden:
    • getKontonummer() — gibt Kontonummer zurück
    • getKontostand() — gibt Kontostand zurück
    • einzahlen(double betrag) — erhöht Kontostand (nur positive Beträge!)
    • abheben(double betrag, String pin) — verringert Kontostand (prüft PIN!)
    • pinAendern(String altePin, String neuePin) — ändert PIN (prüft alte PIN!)
  3. Validierungen:
    • Kontonummer darf nicht null/leer sein
    • Beträge müssen positiv sein
    • PIN muss genau 4 Ziffern haben
    • Kontostand darf nicht negativ werden

Lösung: Findest du am Anfang von Tag 4! 🚀


❓ FAQ — Häufig gestellte Fragen

Frage 1: Muss wirklich JEDES Attribut private sein?

Fast immer ja. Ausnahmen: Konstanten (public static final), und manchmal bei sehr einfachen Datenklassen. Aber als Anfänger: Mach alles private.


Frage 2: Generiert die IDE Getter/Setter automatisch?

Ja! In IntelliJ: Alt+Insert → „Getter and Setter“. In Eclipse: Source → „Generate Getters and Setters“. In VS Code: Rechtsklick → „Source Action“.


Frage 3: Was ist besser: Lombok oder manuelle Getter/Setter?

Beides hat Vor- und Nachteile:

  • Lombok: Weniger Code, schneller, aber zusätzliche Dependency
  • Manuell: Mehr Kontrolle, einfacher zu debuggen, kein Extra-Setup

In Firmen-Projekten ist Lombok sehr verbreitet. Für den Kurs lernen wir beides.


Frage 4: Kann ich Getter/Setter auch private machen?

Ja! Manchmal nützlich für interne Logik:

private void setIntern(int wert) {
    // Nur innerhalb der Klasse nutzbar
}

Frage 5: Was ist der Unterschied zwischen final und private?

  • private = Wer kann zugreifen (Sichtbarkeit)
  • final = Kann der Wert geändert werden (Veränderlichkeit)

Du kannst beides kombinieren: private final String id;


Frage 6: Wann nutze ich protected?

Wenn Subklassen (Kindklassen bei Vererbung) auf ein Attribut oder eine Methode zugreifen sollen. Dazu mehr in Tag 6!


Frage 7: Bernd hat mal gesagt „Getter und Setter sind ein Code Smell“. Stimmt das?

schmunzelt Typisch Bernd. Was er meint: Wenn du NUR stupide Getter/Setter hast ohne Logik, dann könntest du auch gleich public nehmen. Der Mehrwert kommt durch Validierung und Kontrollierte Änderungen.

Real talk: Er hat einen Punkt. Aber als Anfänger ist „private + Getter/Setter“ ein guter Default. Später kannst du optimieren. Bernd optimiert halt von Anfang an — nach 40 Jahren Erfahrung. 🤷


📚 Quiz-Lösungen

Frage 1: Welche vier Sichtbarkeitsmodifier gibt es in Java?

Antwort:

  1. public — überall sichtbar
  2. protected — Klasse + Package + Subklassen
  3. (default/package-private) — Klasse + Package
  4. private — nur eigene Klasse

Frage 2: Was ist der empfohlene Modifier für Attribute und warum?

Antwort:

private ist der empfohlene Modifier für Attribute, weil:

  • Daten sind geschützt vor direktem Zugriff
  • Validierung ist möglich (über Setter)
  • Interne Implementierung kann geändert werden ohne die API zu brechen
  • Debugging ist einfacher (eine Stelle für Änderungen)

Frage 3: Wie heißt der Getter für ein boolean-Attribut aktiv?

Antwort:

isAktiv() — bei boolean verwendet man is statt get (JavaBeans-Konvention).


Frage 4: Was ist der Unterschied zwischen protected und package-private (default)?

Antwort:

protectedpackage-private
Gleiche Klasse
Gleiches Package
Subklasse (anderes Package)
Überall sonst

protected erlaubt zusätzlich Zugriff aus Subklassen, auch wenn sie in anderen Packages sind.


Frage 5: Was ist das Problem und wie löst du es?

public class Konto {
    public double kontostand;  // PROBLEM!
}

Antwort:

Problem: kontostand ist public, also kann jeder direkt darauf zugreifen und jeden Wert setzen — auch negative oder unrealistische.

Lösung:

public class Konto {
    private double kontostand;
    
    public double getKontostand() {
        return kontostand;
    }
    
    public void einzahlen(double betrag) {
        if (betrag <= 0) {
            throw new IllegalArgumentException("Betrag muss positiv sein!");
        }
        kontostand += betrag;
    }
    
    public void abheben(double betrag) {
        if (betrag <= 0) {
            throw new IllegalArgumentException("Betrag muss positiv sein!");
        }
        if (betrag > kontostand) {
            throw new IllegalArgumentException("Nicht genug Guthaben!");
        }
        kontostand -= betrag;
    }
}

🎉 Tag 3 geschafft!

Du hast es geschafft! 🚀

Das hast du heute gelernt:

  • ✅ Die 4 Sichtbarkeitsmodifier und ihre Bedeutung
  • ✅ Warum Kapselung wichtig ist (Schutz, Validierung, Flexibilität)
  • ✅ Getter und Setter richtig implementieren
  • ✅ Die JavaBeans-Namenskonvention

Ab jetzt: Mach Attribute private. Immer. Es wird zur Gewohnheit werden — und dein zukünftiges Ich wird dir danken! 💪


🔮 Wie geht’s weiter?

Morgen in Tag 4: Konstruktoren

Heute hast du gelernt, wie du Attribute schützt. Aber wie initialisierst du ein Objekt sinnvoll? new Auto() erzeugt ein Auto ohne Farbe, ohne PS, ohne alles.

Morgen lernst du:

  • Konstruktoren — Objekte richtig initialisieren
  • Konstruktorüberladung — mehrere Wege ein Objekt zu erzeugen
  • this() — Konstruktoren verketten

Das wird praktisch! 🎯


📦 Downloads

Starter-Projekt für Tag 3:

⬇️ Tag03_Datenkapselung.zip — Komplettes Maven-Projekt

Inhalt:

Tag03_Datenkapselung/
├── pom.xml
├── README.md
└── src/main/java/
    └── de/javafleet/oop/
        ├── Main.java
        └── model/
            ├── Auto.java         (gekapselt)
            └── AutoUnsafe.java   (zum Vergleich: ungekapselt)

Quick Start:

cd Tag03_Datenkapselung
mvn compile
mvn exec:java

🔧 Troubleshooting

Problem: „has private access“

error: farbe has private access in Auto
    auto.farbe = "Rot";
        ^

Lösung: Du versuchst, auf ein privates Attribut direkt zuzugreifen. Nutze den Setter:

auto.setFarbe("Rot");  // ✅ Richtig

Problem: „cannot find symbol: method setXxx“

error: cannot find symbol
    auto.setKilometerstand(100);
        ^
  symbol: method setKilometerstand(int)

Lösung: Es gibt keinen Setter für dieses Attribut. Das ist möglicherweise Absicht! Prüfe, ob es eine andere Methode gibt (z.B. fahren(int km)).


Problem: NullPointerException bei Validierung

public void setName(String name) {
    if (name.isBlank()) {  // ❌ NullPointerException wenn name == null!
        throw new IllegalArgumentException("...");
    }
}

Lösung: Prüfe zuerst auf null:

if (name == null || name.isBlank()) {  // ✅ Null-safe
    throw new IllegalArgumentException("...");
}

🔗 Resources & Links

🟢 Für Einsteiger

RessourceBeschreibungSprache
Oracle — Access ControlOffizielle Doku🇬🇧
W3Schools — Java EncapsulationEinfache Erklärungen🇬🇧
Java ist auch eine Insel — KapselungKostenloses Buch🇩🇪

🟡 Für Fortgeschrittene

RessourceBeschreibungSprache
Baeldung — Java Access ModifiersTiefgehende Erklärung🇬🇧
Effective Java — Item 16„Favor composition over inheritance“🇬🇧
Java Records GuideImmutable Data Classes🇬🇧

🛠️ Tools

ToolBeschreibungLink
LombokGetter/Setter automatischprojectlombok.org
IntelliJ GeneratorAlt+Insert für Getter/SetterEingebaut

💬 Feedback

Fragen? Schreib mir:

  • Nova: nova.trent@java-developer.online

Feedback zum Kurs? Nutze den 👎-Button unten!


👋 Bis morgen!

Tag 3 ist durch. Deine Objekte sind jetzt geschützt!

Morgen: Konstruktoren — wie du Objekte von Anfang an richtig initialisierst.

See you! 🚀


Nova Trent
Junior Entwicklerin bei Java Fleet Systems Consulting
„Private Attribute, public Methoden. So einfach ist das!“ 🔒


Tags: #Java #OOP #Kapselung #Encapsulation #Private #Getter #Setter #Tutorial

© 2025 Java Fleet Systems Consulting | java-developer.online

Autor

  • Ensign Nova Trent

    24 Jahre alt, frisch von der Universität als Junior Entwicklerin bei Java Fleet Systems Consulting. Nova ist brilliant in Algorithmen und Datenstrukturen, aber neu in der praktischen Java-Enterprise-Entwicklung. Sie brennt darauf, ihre ersten echten Projekte zu bauen und entdeckt dabei die Lücke zwischen Uni-Theorie und Entwickler-Realität. Sie liebt Star Treck das ist der Grund warum alle Sie Ensign Nova nennen und arbeitet daraufhin das sie Ihren ersten Knopf am Kragen bekommt.