공공부하자개발 · 영어 학습 노트
자바
고급모던 자바와 성능0/10 완료
  • 01제네릭과 와일드카드
  • 02멀티스레드와 동기화
  • 03람다식과 함수형 인터페이스
  • 04Stream API와 병렬 처리
  • 05Optional로 NPE 방지
  • 06메서드 활용 패턴 (고급)
  • 07Java 21 모던 문법
  • 08어노테이션·리플렉션·동적 프록시
  • 09CompletableFuture 심화와 가상 스레드 실전
  • 10JVM 메모리·GC·OOM 진단
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › 고급 › 07 / 10

Java 21 모던 문법

var, record, 텍스트 블록, switch 식, 패턴 매칭, sealed
섹션 7진행 0 / 10
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6연습 문제7정리‹ 이전다음 ›

6. 연습 문제

문제 1

Shape 에 Ring(double outer, double inner) 을 추가하세요. 압축 생성자에서 inner < outer 를 검증하고, Main.section5 의 switch 가 컴파일 오류를 내는 것을 확인한 뒤 case 를 추가하세요. area() 는 바깥 원 넓이에서 안쪽 원 넓이를 뺀 값입니다.

정답 보기
java
public sealed interface Shape permits Circle, Rect, Triangle, Ring { double area(); }

record Ring(double outer, double inner) implements Shape {
    Ring { if (inner <= 0 || inner >= outer) throw new IllegalArgumentException("0 < inner < outer"); }
    public double area() { return Math.PI * (outer * outer - inner * inner); }
}
// section5 의 switch 에 추가
case Ring(double o, double i) -> "고리 " + o + "/" + i;

permits 에 넣지 않으면 Ring 쪽에서 "sealed 계층에 허용되지 않음" 오류가 나고, 넣으면 switch 쪽에서 완전성 오류가 납니다. 두 오류가 "추가할 곳" 을 전부 알려 줍니다.

문제 2

PaymentResult 에 Refunded(String txId, BigDecimal amount, String reason) 을 추가하고, handle 에서 환불 금액이 10,000원 이상이면 "환불 승인 대기", 미만이면 "환불 완료" 로 나누세요. 해체 패턴과 when 을 쓰세요.

정답 보기
java
record Refunded(String txId, BigDecimal amount, String reason) implements PaymentResult {}
// permits 에 PaymentResult.Refunded 추가

case PaymentResult.Refunded(String tx, BigDecimal amt, String why) when amt.compareTo(new BigDecimal("10000")) >= 0
        -> "환불 승인 대기 " + tx + " (" + why + ")";
case PaymentResult.Refunded(String tx, BigDecimal amt, String why) -> "환불 완료 " + tx;

BigDecimal 비교는 compareTo 입니다(중급 07). 가드 case 를 먼저 두어야 합니다.

문제 3

다음 Java 8 식 코드를 var, record, switch 식, instanceof 패턴으로 다시 쓰세요. 줄 수가 얼마나 줄어드는지 세어 보세요.

java
public class Money { private final BigDecimal amount; private final String currency;
    public Money(BigDecimal a, String c) { amount = a; currency = c; }
    public BigDecimal getAmount() { return amount; } public String getCurrency() { return currency; }
    @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Money)) return false;
        Money m = (Money) o; return amount.equals(m.amount) && currency.equals(m.currency); }
    @Override public int hashCode() { return Objects.hash(amount, currency); }
    @Override public String toString() { return "Money{" + amount + " " + currency + "}"; } }

String label(Object o) { if (o instanceof Money) { Money m = (Money) o; if (m.getCurrency().equals("KRW")) return m.getAmount() + "원"; else return m.getAmount() + " " + m.getCurrency(); } return "?"; }
정답 보기
java
record Money(BigDecimal amount, String currency) {}

String label(Object o) {
    return switch (o) {
        case Money(BigDecimal amt, String cur) when cur.equals("KRW") -> amt + "원";
        case Money(BigDecimal amt, String cur) -> amt + " " + cur;
        default -> "?";
    };
}

클래스 8줄이 1줄, 메서드 5줄이 5줄이지만 캐스팅과 중첩 if 가 사라졌습니다. Object 를 받는 switch 는 경우가 무한하므로 default 가 필요합니다.

연습 문제
  • 문제 1
  • 문제 2
  • 문제 3
이전 섹션5 자주 하는 실수 (Tip)6 / 7다음 섹션7 정리