Best practices for Optional
Anvend orElse, orElseGet og orElseThrow, og undgå almindelige anti-mønstre med Optional.
Best practices for Optional er en gratis Java Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Java Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Java Academy-kurset indeholder 4 lektioner i alt.
Bedste fremgangsmåder for Optional
Optional er et effektivt værktøj, når det bruges korrekt. Denne lektion gennemgår, hvad du bør og ikke bør gøre, med konkrete eksempler fra virkelige kodebaser.
Gør: Brug Optional som returtype
Den primære anvendelse af Optional er som returtype fra metoder, der måske ikke finder eller opretter en værdi.
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 conditionUndgå: Optional som felt
Optional-felter medfører ekstra objektomkostninger og gør serialisering mere kompliceret. Brug null eller en markørværdi til valgfrie felter 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()); // falseUndgå: Optional som metodeparameter
Optional-parametre tvinger kaldende kode til at pakke værdier ind i Optional uden grund. Brug overloadning 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") — cleanUndgå: Optional i samlinger
Anbring aldrig Optional-værdier i en List, Set eller som en Map-værdi. Tomme Optional-værdier i samlinger er meningsløse — udelad blot posten.
// 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");Gør: Brug orElseGet til dyre standardværdier
Når standardværdien kræver beregning (databaseforespørgsel, netværkskald), skal du altid bruge orElseGet — leverandøren kaldes kun, når det er nødvendigt.
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");Gør: Brug orElseThrow til nødvendige værdier
Når en manglende værdi er en programmeringsfejl eller en overtrædelse af en invariant, skal du bruge orElseThrow med en beskrivende undtagelse.
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()
Undgå antimønstret, hvor du kontrollerer isPresent() og derefter kalder get(). Det er ikke bedre end en null-kontrol og modarbejder formålet 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");Bedste fremgangsmåde ved kædning
Opbyg en ren kæde: find → filter → transformér → reserveværdi. Hvert trin forklarer sig 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 servicelaget
Et realistisk eksempel på servicelaget, der følger de bedste fremgangsmåder.
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 værktøjer til null-sikkerhed
Optional supplerer @Nullable- og @NonNull-annotations samt værktøjer som SpotBugs og NullAway for at give fuldstændig dækning af null-sikkerhed.
// 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 typesHurtig kontrol
Hvad er der galt med følgende kode?
if (opt.isPresent()) {
process(opt.get());
}Opsummering: Bedste fremgangsmåder for Optional
Vigtigste pointer:
- Brug kun Optional som returtype — aldrig som felt eller metodeparameter
- Foretræk orElseGet frem for orElse, når standardværdien er dyr at beregne
- Brug orElseThrow, når en manglende værdi repræsenterer en programmeringsfejl
- Undgå isPresent() + get() — brug ifPresent, map eller orElse i stedet
- Anbring aldrig Optional i samlinger — filtrér streams i stedet
- Opbyg læsbare kæder: filter → map → orElse for et tydeligt dataflow
Lær Java med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 104
- Lektioner
- 374
Ofte stillede spørgsmål
Er lektionen “Best practices for Optional” gratis?
Ja — hele teksten til “Best practices for Optional” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Java Academy-kurset, skal du opgradere til CoddyKit PRO. Java Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Best practices for Optional”?
Anvend orElse, orElseGet og orElseThrow, og undgå almindelige anti-mønstre med Optional. Du øver dig i Java Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Java Academy?
Der kræves ingen tidligere erfaring. Java Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.
Hvor lang tid tager lektionen “Best practices for Optional”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Java Academy-lektion?
Ja. Alle Java Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Hvorfor findes Optional?
- Oprettelse og inspektion af Optionals
- Transformation af Optionals: map og flatMap
- Best practices for Optional