ProgrammatieJava ontwikkelaar

Wat zijn immutable-objecten in Java, wat is hun waarde en hoe implementeer je correct je eigen immutable klasse?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

Immutable-objecten zijn objecten waarvan de toestand niet kan worden gewijzigd na creatie. Hun belangrijkste eigenschappen zijn:

  • Alle velden final;
  • Bevatten geen setters;
  • Er kan geen wijzigbare referentie naar interne objecten (zoals collecties) worden verkregen.

Voordelen van immutable-objecten:

  • Veilig voor multithread-toegang (thread-safe);
  • Makkelijk te cachen en opnieuw te gebruiken als sleutels in collecties;
  • Eenvoudiger voor debugging en testen;
  • Minder bugs door onverwachte veranderingen in toestand.

Voorbeeld van implementatie van een immutable klasse:

public final class Person { private final String name; private final int age; private final List<String> phones; public Person(String name, int age, List<String> phones) { this.name = name; this.age = age; // Bescherming tegen mutatie van de doorgegeven lijst this.phones = Collections.unmodifiableList(new ArrayList<>(phones)); } public String getName() { return name; } public int getAge() { return age; } public List<String> getPhones() { return phones; } // Retourneer read-only lijst }

Vragen met een addertje onder het gras.

Waarom is String immutable in Java en wat zou er gebeuren als dat niet het geval was? Veel mensen antwoorden "voor de veiligheid", maar wat betekent dat in de praktijk?

Antwoord:

String wordt op veel plaatsen gebruikt: als sleutels in collecties, in beveiligingslogica (bijvoorbeeld wachtwoorden). Als een string op één referentie zou kunnen worden gewijzigd, zou dit invloed hebben op alle andere referenties naar hetzelfde object, wat de juiste werking van collecties (bijvoorbeeld HashMap — bij het berekenen van hashCode) onmogelijk zou maken en zou kunnen leiden tot beveiligingskwetsbaarheden.

Voorbeelden van echte fouten door gebrek aan kennis van de subtiliteiten van het onderwerp.


Verhaal

In een groot bankproject werden interne collecties (lijst van transacties) doorgegeven met een gewone getter. Als gevolg daarvan kon de lijst van buitenaf worden gewijzigd, waardoor de invarianties werden geschonden (bijvoorbeeld het toevoegen van een transactie met een onjuiste datum). Dit leidde tot verlies van gegevens, totdat men begon te retourneren Collections.unmodifiableList.

Verhaal

In de rootklasse van de configuratie werden niet-beveiligde objectvelden (Date, List) opgeslagen. In één van de threads werd de configuratie gewijzigd, en in de andere werden verouderde of inconsistente gegevens verkregen, waardoor de bedrijfsalgoritme niet correct werkte.

Verhaal

In het inlogsysteem werden wachtwoorden opgeslagen in een wijzigbaar object. Door onveilige toegang "lekke" ineens het wachtwoord van een andere gebruiker, omdat hetzelfde exemplaar van het object door veel threads werd gebruikt.