04 · Java language in depth / LESSON 15 OF 102
Optional, time, and exact money
Choose types that make absence, time zones, and decimal precision explicit.
Before this lesson: Records, enums, and defensive copies
Understand the topic
Optional is useful for a return value that may be missing. Prefer map or orElseGet to an unconditional get. Use Instant for a point on the timeline, LocalDate for a calendar date, and a ZoneId when translating between them.
Use BigDecimal constructed from decimal strings for exact decimal amounts. Specify rounding for division and setScale. Inject Clock into time-dependent services so tests can control now without sleeping.
EXAMPLE · JAVA
Main.java
import java.math.*;
import java.time.*;
public class Main {
public static void main(String[] args) {
var price = new BigDecimal("19.99");
System.out.println(price.multiply(new BigDecimal("3")));
Clock clock = Clock.fixed(Instant.parse("2026-01-01T00:00:00Z"), ZoneOffset.UTC);
System.out.println(LocalDate.now(clock));
}
}What to expect
Prints 59.97 and 2026-01-01 deterministically.
YOUR TURN
Put it into practice
- 01Implement a due-date reminder using an injected Clock.
- 02Test just before and after midnight in two zones; calculate a decimal total with an explicit rounding policy.
- 03Verify: Tests do not depend on the real clock and money calculations preserve the declared scale.
Pass a quiz or complete a lab to check today’s streak. Each lesson counts once per day, including when you review it later.
UNDER THE HOOD
Build the mental model
Choose types that make absence, time zones, and decimal precision explicit.
- 01Optional is useful for a return value that may be missing. Prefer map or orElseGet to an unconditional get. Use Instant for a point on the timeline, LocalDate for a calendar date, and a ZoneId when translating between them.
- 02Use BigDecimal constructed from decimal strings for exact decimal amounts. Specify rounding for division and setScale. Inject Clock into time-dependent services so tests can control now without sleeping.
- 03Trace the example: Prints 59.97 and 2026-01-01 deterministically.
A mistake worth avoiding
A deadline passes a test locally but fails in another timezone.
DEBUGGING ROOM
Something broke. Where do you look?
A deadline passes a test locally but fails in another timezone.
Before revealing the diagnosis, write down your first investigation step.
CHECK YOUR UNDERSTANDING
Which type represents a timezone-independent point on the timeline?
BUILD IT YOURSELF
Implement a due-date reminder using an injected Clock.
- 1.Implement a due-date reminder using an injected Clock.
- 2.Test just before and after midnight in two zones; calculate a decimal total with an explicit rounding policy.
- 3.Reproduce this failure, then repair it: A deadline passes a test locally but fails in another timezone.
Acceptance checklist
Lab completion is your self-report. Knowledge checks do not certify project quality.
RETRIEVE IT FROM MEMORY
Which type represents a timezone-independent point on the timeline?
Revisit this lesson in three days after a successful check or lab.
Ready for the next step?
Tests do not depend on the real clock and money calculations preserve the declared scale.
Reading is separate from passing a knowledge check or completing a lab.