Beste praksis for Optional
Bruk orElse, orElseGet og orElseThrow, og unngå vanlige anti-mønstre for Optional.
Beste praksis for Optional er en gratis leksjon i Java Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Java Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Java Academy inneholder totalt 4 leksjoner.
Beste praksis for Optional
Optional er et kraftig verktøy når det brukes riktig. Denne leksjonen dekker hva du bør og ikke bør gjøre, med konkrete eksempler fra kodebaser i den virkelige verden.
Bør: Bruk Optional som returtype
Det primære bruksområdet for Optional er som returtype fra metoder som kanskje ikke finner eller produserer en verdi.
import java.util.Optional;
// Good: signals to caller that result might be absent
public Optional<User> findByUsername(String username) { ... }
public Optional<Config> getConfig(String key) { ... }
public Optional<String> getHeader(String name) { ... }
// These are all cases where absence is a normal outcome,
// not an exceptional conditionBør ikke: Optional som felt
Optional-felt gir ekstra objektkostnad og gjør serialisering mer komplisert. Bruk null eller en sentinelverdi for valgfrie felt inne i klasser.
// BAD
class User {
private Optional<String> middleName; // wrong
}
// GOOD: use null for absent optional field
class User {
private final String middleName; // null = absent
public Optional<String> middleName() {
return Optional.ofNullable(middleName); // expose as Optional in getter
}
}
User u = new User(null); // null field
System.out.println(u.middleName().isPresent()); // falseBør ikke: Optional som metodeparameter
Optional-parametere tvinger kallere til å pakke inn verdier i Optional uten at det er nødvendig. Bruk overlasting eller @Nullable i stedet.
// BAD
void sendNotification(String message, Optional<String> subject) { ... }
// caller must write: sendNotification("Hello", Optional.of("News"))
// GOOD: overloading
void sendNotification(String message) { sendNotification(message, null); }
void sendNotification(String message, String subject) {
// subject may be null
}
// caller writes: sendNotification("Hello", "News") — cleanBør ikke: Optional i samlinger
Legg aldri Optional-er i en List, Set eller som Map-verdi. Tomme Optional-er i samlinger er meningsløse – utelat oppføringen i stedet.
// BAD: List of Optionals
List<Optional<User>> results = ...; // meaningless empty Optionals
// GOOD: List of present values only
List<User> presentUsers = maybeUsers.stream()
.flatMap(Optional::stream)
.collect(Collectors.toList());
// BAD: Map with Optional values
Map<String, Optional<String>> config = ...;
// GOOD: just use null or omit the key for absent values
Map<String, String> config2 = ...;
String value = config2.getOrDefault("key", "default");Bør: orElseGet for kostbare standardverdier
Når standardverdien krever beregning (databaseoppslag, nettverkskall), bør du alltid bruke orElseGet – leverandøren kalles bare når det er nødvendig.
import java.util.Optional;
// BAD: buildDefault() always called, even when value is present!
String config = getConfig("timeout").orElse(buildDefault());
// GOOD: supplier called lazily only when empty
String config2 = getConfig("timeout").orElseGet(() -> buildDefault());
// Or with method reference:
String config3 = getConfig("timeout").orElseGet(this::buildDefault);
// For cheap literals, orElse is fine
String name = getConfig("name").orElse("default");Bør: orElseThrow for nødvendige verdier
Når en manglende verdi skyldes en programmeringsfeil eller et brudd på en invariant, bør du bruke orElseThrow med et beskrivende unntak.
import java.util.Optional;
// Good: throw when absence is an error
User user = userRepository.findById(userId)
.orElseThrow(() -> new UserNotFoundException("User not found: " + userId));
// Good: in validation code
String apiKey = Optional.ofNullable(System.getenv("API_KEY"))
.orElseThrow(() -> new IllegalStateException(
"API_KEY environment variable is required"));
System.out.println("Key found: " + apiKey.length() + " chars");Antimønster: isPresent + get()
Unngå antimønsteret der du kontrollerer isPresent() og deretter kaller get(). Dette er ikke bedre enn en null-kontroll og motvirker hensikten med Optional.
import java.util.Optional;
Optional<String> opt = findValue();
// BAD: isPresent() + get() — no improvement over null check
if (opt.isPresent()) {
String val = opt.get();
process(val);
}
// GOOD: use the functional API
opt.ifPresent(this::process);
// GOOD: transform and return
return opt.map(this::process).orElse(null);
// GOOD: provide a default
String result = opt.orElse("default");Beste praksis for kjeding
Bygg en ryddig kjede: finn → filtrer → transformer → reserveverdi. Hvert trinn forklarer seg selv.
import java.util.Optional;
record User(long id, String plan, boolean active) {}
static Optional<User> findUser(long id) { return Optional.empty(); }
String result = findUser(42L)
.filter(User::active) // keep only active users
.filter(u -> "PRO".equals(u.plan())) // keep only PRO users
.map(u -> "Welcome, Pro user #" + u.id()) // transform
.orElse("Upgrade to Pro!"); // fallback
System.out.println(result); // Upgrade to Pro!Optional i tjenestelaget
Et realistisk eksempel fra tjenestelaget som følger beste praksis.
import java.util.Optional;
class OrderService {
public Optional<OrderSummary> getOrderSummary(long orderId) {
return orderRepo.findById(orderId)
.filter(o -> !o.isCancelled())
.map(this::toSummary);
}
public OrderSummary requireOrderSummary(long orderId) {
return getOrderSummary(orderId)
.orElseThrow(() -> new OrderNotFoundException(orderId));
}
private OrderSummary toSummary(Order o) { return new OrderSummary(o); }
}
// API callers choose: Optional (handle absence) or require (exception)Optional og verktøy for null-sikkerhet
Optional utfyller @Nullable- og @NonNull-annotasjoner samt verktøy som SpotBugs/NullAway, slik at du får full dekning for null-sikkerhet.
// Annotation-based: declares intent for in-class nulls
import org.jetbrains.annotations.*;
class ProductService {
@Nullable // may return null — for framework/bean use
public String getCachedName(String id) { return cache.get(id); }
// Optional — for service API that handles absence
public Optional<Product> findProduct(String id) {
return repo.findById(id);
}
}
// Use @Nullable for fields/parameters; Optional for return typesHurtigsjekk
Hva er galt med følgende kode?
if (opt.isPresent()) {
process(opt.get());
}Oppsummering: Beste praksis for Optional
Viktigste punkter:
- Bruk Optional bare som returtype – aldri som felt eller metodeparameter
- Foretrekk orElseGet fremfor orElse når standardverdien er kostbar å beregne
- Bruk orElseThrow når fravær representerer en programmeringsfeil
- Unngå isPresent() + get() – bruk ifPresent, map eller orElse i stedet
- Legg aldri Optional i samlinger – filtrer streams i stedet
- Bygg lesbare kjeder: filter → map → orElse for en tydelig datastrøm
Lær deg Java med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 104
- Leksjoner
- 374
Ofte stilte spørsmål
Er leksjonen «Beste praksis for Optional» gratis?
Ja – hele teksten i «Beste praksis for Optional» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Java Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Java Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Beste praksis for Optional»?
Bruk orElse, orElseGet og orElseThrow, og unngå vanlige anti-mønstre for Optional. Du øver på Java Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Java Academy?
Ingen tidligere erfaring er nødvendig. Java Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.
Hvor lang tid tar leksjonen «Beste praksis for Optional»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Java Academy-leksjonen?
Ja. Alle Java Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Hvorfor Optional finnes
- Opprette og undersøke Optional-verdier
- Transformere Optional-verdier: map og flatMap
- Beste praksis for Optional