Inner classes en toegang tot de buitenste klasse
Gebruik niet-statische inner classes die een verwijzing naar de instantie van de buitenste klasse bevatten.
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.0Leden 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: 10Iteratorpatroon 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 5Gebeurtenislisteners 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: aliceInnerlijke 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 itselfWanneer 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
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
- Statische geneste klassen
- Inner classes en toegang tot de buitenste klasse
- Lokale en anonieme klassen
- De juiste nestingstrategie kiezen