공공부하자개발 · 영어 학습 노트
자바
중급객체지향과 코어 라이브러리0/9 완료
  • 01상속, 다형성, 오버라이딩
  • 02추상 클래스 vs 인터페이스
  • 03예외 처리
  • 04java.lang 심화
  • 05컬렉션 프레임워크 딥다이브
  • 06메서드 활용 패턴 (중급)
  • 07Object 메서드와 비교
  • 08java.time 실무 날짜 계산
  • 09HTTP 와 JSON 기초
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › 중급 › 03 / 9

예외 처리

섹션 7진행 0 / 9
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6연습 문제7정리‹ 이전다음 ›

6. 연습 문제

문제 1: 실행 순서 예측

다음 코드의 출력을 예측하라.

java
static String test() {
    StringBuilder sb = new StringBuilder();
    try {
        sb.append("A");
        throw new RuntimeException();
    } catch (RuntimeException e) {
        sb.append("B");
        return sb.toString();
    } finally {
        sb.append("C");
        System.out.println("finally: " + sb);
    }
}
System.out.println("반환: " + test());
정답 보기
java
// 출력:
// finally: ABC
// 반환: AB
//
// 해설: catch에서 return sb.toString()이 평가되어 "AB"가 반환값으로 확정된다.
// 그 뒤 finally가 실행되어 sb에 "C"가 붙지만(sb는 참조이므로 객체 자체는 변함),
// 이미 확정된 반환값은 "AB"라는 별도의 String이므로 영향을 받지 않는다.

문제 2: 회원 도메인 예외 계층

MemberException(abstract, RuntimeException 상속, String code 필드)을 부모로, MemberNotFoundException(long id)(코드 "M404")과 DuplicateEmailException(String email)(코드 "M409")을 만들어라.

두 예외를 던지고 catch (MemberException e) 하나로 잡아 code: message 형식으로 출력하라.

정답 보기
java
abstract class MemberException extends RuntimeException {
    private final String code;
    protected MemberException(String code, String message) {
        super(message);
        this.code = code;
    }
    String getCode() { return code; }
}

class MemberNotFoundException extends MemberException {
    MemberNotFoundException(long id) { super("M404", "회원 없음: id=" + id); }
}

class DuplicateEmailException extends MemberException {
    DuplicateEmailException(String email) { super("M409", "이미 가입된 이메일: " + email); }
}

public class Main {
    public static void main(String[] args) {
        Runnable[] actions = {
            () -> { throw new MemberNotFoundException(42); },
            () -> { throw new DuplicateEmailException("a@b.com"); }
        };
        for (Runnable r : actions) {
            try {
                r.run();
            } catch (MemberException e) {
                System.out.println(e.getCode() + ": " + e.getMessage());
            }
        }
        // 출력:
        // M404: 회원 없음: id=42
        // M409: 이미 가입된 이메일: a@b.com
    }
}

문제 3: AutoCloseable 구현과 닫힘 순서

Connection과 Statement라는 두 AutoCloseable 클래스를 만들어 열림/닫힘 시 이름을 출력하게 하고, try-with-resources로 Connection → Statement 순서로 열어 본문에서 "쿼리 실행"을 출력하라. 전체 출력 순서를 확인하고, 왜 그 순서인지 한 줄로 설명하라.

정답 보기
java
class Connection implements AutoCloseable {
    Connection() { System.out.println("Connection 열림"); }
    @Override public void close() { System.out.println("Connection 닫힘"); }
}

class Statement implements AutoCloseable {
    Statement(Connection c) { System.out.println("Statement 열림"); }
    @Override public void close() { System.out.println("Statement 닫힘"); }
}

public class Main {
    public static void main(String[] args) {
        try (Connection conn = new Connection();
             Statement stmt = new Statement(conn)) {
            System.out.println("쿼리 실행");
        }
        // 출력:
        // Connection 열림
        // Statement 열림
        // 쿼리 실행
        // Statement 닫힘
        // Connection 닫힘
        //
        // 이유: Statement는 Connection에 의존하므로 의존하는 쪽(나중에 연 것)을 먼저 닫아야
        // 닫힌 커넥션 위에서 Statement를 정리하는 상황을 피할 수 있다. 선언 역순.
    }
}
연습 문제
  • 문제 1: 실행 순서 예측
  • 문제 2: 회원 도메인 예외 계층
  • 문제 3: AutoCloseable 구현과 닫힘 순서
이전 섹션5 자주 하는 실수 (Tip)6 / 7다음 섹션7 정리