Java Academy · Les

Inner classes en toegang tot de buitenste klasse

Gebruik niet-statische inner classes die een verwijzing naar de instantie van de buitenste klasse bevatten.

Les 2 van 413 stappen

Inner classes en toegang tot de buitenste klasse is een gratis Java Academy-les op CoddyKit. Dit is les 2 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Java Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Java Academy bevat in totaal 4 lessen.

Innerlijke klassen

Een niet-statische innerlijke klasse bevat een impliciete verwijzing naar de instantie van de omringende buitenste klasse. Ze heeft toegang tot alle leden van de buitenste klasse, ook tot private leden.

Een innerlijke klasse declareren en gebruiken

Maak een instantie van een innerlijke klasse alleen via een instantie van de buitenste klasse met outer.new InnerClass().

class BankAccount {
    private double balance;
    private String owner;

    BankAccount(String owner, double initial) {
        this.owner = owner; this.balance = initial;
    }

    class Transaction {
        void deposit(double amount) {
            balance += amount; // accesses outer field directly
            System.out.println(owner + " deposited " + amount);
        }
    }
}

BankAccount acct = new BankAccount("Alice", 500);
BankAccount.Transaction tx = acct.new Transaction();
tx.deposit(100); // Alice deposited 100.0

Leden van de buitenste klasse benaderen

Innerlijke klassen hebben toegang tot alle leden van de buitenste klasse — zelfs tot private velden en methoden.

class Encryption {
    private final String secretKey = "s3cr3t"; // private!

    class Encryptor {
        String encrypt(String data) {
            // Inner class accesses private outer field
            return data + "|" + secretKey.hashCode();
        }
    }

    class Decryptor {
        String decrypt(String encrypted) {
            int idx = encrypted.lastIndexOf('|');
            return encrypted.substring(0, idx);
        }
    }
}

Naamverberging met this

Wanneer een innerlijke klasse een veld heeft met dezelfde naam als de buitenste klasse, gebruik je OuterClass.this.field om naar het veld van de buitenste klasse te verwijzen.

class Outer {
    int value = 10;

    class Inner {
        int value = 20; // shadows outer.value

        void printBoth() {
            System.out.println("Inner value: " + value);         // 20
            System.out.println("Outer value: " + Outer.this.value); // 10
        }
    }
}

new Outer().new Inner().printBoth();
// Inner value: 20
// Outer value: 10

Iteratorpatroon met een innerlijke klasse

Een klassieke toepassing: een iterator implementeren als innerlijke klasse die toegang heeft tot de private gegevens van de omringende collectie.

class NumberRange implements Iterable<Integer> {
    private final int start;
    private final int end;

    NumberRange(int start, int end) {
        this.start = start; this.end = end;
    }

    @Override
    public java.util.Iterator<Integer> iterator() {
        return new RangeIterator(); // inner class instance
    }

    private class RangeIterator implements java.util.Iterator<Integer> {
        private int current = start; // accesses outer start

        public boolean hasNext() { return current <= end; }
        public Integer next()    { return current++; }
    }
}

for (int n : new NumberRange(1, 5)) System.out.print(n + " ");
// 1 2 3 4 5

Gebeurtenislisteners als innerlijke klassen

GUI- en gebeurtenisgestuurde programmering gebruikt vaak innerlijke klassen om listeners voor gebeurtenissen te implementeren, met toegang tot de toestand van de omringende UI-component.

// Swing-style example (conceptual)
class LoginPanel {
    private String username = "";

    class LoginButtonListener {
        void onButtonClicked() {
            if (username.isEmpty()) {
                System.out.println("Please enter username"); // accesses outer field
            } else {
                System.out.println("Logging in as: " + username);
            }
        }
    }

    void setUsername(String name) { this.username = name; }
}
LoginPanel panel = new LoginPanel();
panel.setUsername("alice");
panel.new LoginButtonListener().onButtonClicked();
// Logging in as: alice

Innerlijke klasse in collecties

Sommige implementaties van collecties gebruiken innerlijke klassen om cursors of weergaven bij te houden die worden ondersteund door de omringende collectie.

class SimpleStack<T> {
    private Object[] elements;
    private int size = 0;

    SimpleStack(int capacity) {
        elements = new Object[capacity];
    }

    void push(T item) {
        if (size >= elements.length) throw new StackOverflowError();
        elements[size++] = item;
    }

    T pop() {
        if (size == 0) throw new java.util.EmptyStackException();
        T item = (T) elements[--size];
        elements[size] = null;
        return item;
    }

    int size() { return size; }
}

Waarschuwing voor geheugenlekken

Instanties van innerlijke klassen bevatten een verwijzing naar de instantie van de buitenste klasse. Als de innerlijke klasse aan de buitenste klasse ontsnapt (bijvoorbeeld doordat ze wordt opgeslagen in een langlevende collectie), kan de buitenste instantie niet door de garbagecollector worden opgeruimd.

// Memory leak: anonymous inner class (implicit outer ref) stored statically
class LeakExample {
    byte[] data = new byte[1024 * 1024]; // 1MB

    // BAD: this Runnable holds a reference to LeakExample.this
    Runnable leak = new Runnable() {
        public void run() { System.out.println(data.length); }
    };
}
// If 'leak' is stored somewhere, LeakExample (and its 1MB) is never GC'd

// FIX: use a static nested class or a lambda that captures only needed values
static Runnable noLeak(byte[] data) {
    return () -> System.out.println(data.length); // captures array, not outer
}

Innerlijke klasse versus lambda

Moderne Java-lambda's vervangen vaak anonieme innerlijke klassen voor interfaces met één methode. Lambda's zijn beknopter, maar hebben GEEN eigen this.

// Old way: anonymous inner class
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("Running (inner class) — this is the Runnable");
    }
};

// Modern: lambda
Runnable r2 = () -> System.out.println("Running (lambda)");

r1.run();
r2.run();

// Lambda this = enclosing class (not the Runnable)
// Inner class this = the Runnable instance itself

Wanneer je innerlijke klassen gebruikt

Gebruik niet-statische innerlijke klassen wanneer:

  • De klasse toegang nodig heeft tot de private toestand van de omringende instantie
  • Elke innerlijke instantie logisch is gekoppeld aan een specifieke buitenste instantie
  • Je het Iterator-patroon gebruikt om doorlooplogica in te kapselen

Praktijk: Pagineerder

Een praktische pagineerder waarbij de innerklasse de paginastatus bijhoudt en toegang heeft tot de buitenste gegevenslijst.

import java.util.*;

class Paginator<T> {
    private final List<T> items;
    private final int pageSize;

    Paginator(List<T> items, int pageSize) {
        this.items = items; this.pageSize = pageSize;
    }

    class Page {
        private int pageIndex = 0;

        List<T> current() {
            int start = pageIndex * pageSize;
            int end = Math.min(start + pageSize, items.size()); // outer
            return start < items.size() ? items.subList(start, end) : List.of();
        }
        boolean hasNext() { return (pageIndex + 1) * pageSize < items.size(); }
        void next() { if (hasNext()) pageIndex++; }
    }
}
Paginator<String> p = new Paginator<>(List.of("a","b","c","d","e"), 2);
Paginator.Page page = p.new Page();
System.out.println(page.current()); // [a, b]
page.next();
System.out.println(page.current()); // [c, d]

Korte controle

Wat bevat een innerklasse (niet-statische klasse) wel en een statisch geneste klasse niet?

Samenvatting: innerklassen en toegang tot de buitenklasse

Belangrijkste punten:

  • Niet-statische innerklassen bevatten een impliciete verwijzing naar de omsluitende buiteninstantie
  • Maak instanties van innerklassen alleen via een buiteninstantie: outer.new Inner()
  • Innerklassen hebben toegang tot alle leden van de buitenklasse, inclusief private velden
  • Gebruik Outer.this.field om velden met dezelfde naam van elkaar te onderscheiden
  • Beste gebruikssituaties: Iterator, gebeurtenislisteners en interne datastructuren
  • Risico: instanties van innerklassen voorkomen dat buiteninstanties door automatische geheugenopruiming worden vrijgegeven
Gratis beginnen

Leer Java met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
104
Lessen
374

Veelgestelde vragen

Is de les “Inner classes en toegang tot de buitenste klasse” gratis?

Ja — de volledige tekst van “Inner classes en toegang tot de buitenste klasse” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Java Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Java Academy bevat in totaal 4 lessen.

Wat leer ik in “Inner classes en toegang tot de buitenste klasse”?

Gebruik niet-statische inner classes die een verwijzing naar de instantie van de buitenste klasse bevatten. Je oefent met Java Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Java Academy te beginnen?

Ervaring vooraf is niet nodig. Java Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 2 van 4.

Hoe lang duurt de les “Inner classes en toegang tot de buitenste klasse”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Java Academy?

Ja. Elke les over Java Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Statische geneste klassen
  2. Inner classes en toegang tot de buitenste klasse
  3. Lokale en anonieme klassen
  4. De juiste nestingstrategie kiezen
← Terug naar Java Academy