λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Java/Java의 정석

Chapter 08 - μ˜ˆμ™Έμ²˜λ¦¬

Chapter 08 - μ˜ˆμ™Έμ²˜λ¦¬

μ˜ˆμ™Έμ²˜λ¦¬

ν”„λ‘œκ·Έλž¨ 였λ₯˜

  • μ’…λ₯˜
    • 컴파일 μ—λŸ¬ : 컴파일 μ‹œμ— λ°œμƒ
    • λŸ°νƒ€μž„ μ—λŸ¬ : μ‹€ν–‰ μ‹œμ— λ°œμƒ
    • 논리적 μ—λŸ¬ : 싀행은 λ˜μ§€λ§Œ, μ˜λ„ν•œ λŒ€λ‘œ μž‘λ™ν•˜μ§€ μ•ŠλŠ” 것
  • λŸ°νƒ€μž„μ—μ„œ μ—λŸ¬μ™€ μ˜ˆμ™Έ
    • μ—λŸ¬λŠ” ν”„λ‘œκ·Έλž¨ μ½”λ“œμ— μ˜ν•΄μ„œ 수슡될 수 μ—†λŠ” μ‹¬κ°ν•œ 였λ₯˜ (λ©”λͺ¨λ¦¬ λΆ€μ‘±, μŠ€νƒμ˜€λ²„ν”Œλ‘œμš°)
    • μ˜ˆμ™ΈλŠ” ν”„λ‘œκ·Έλž¨ μ½”λ“œμ— μ˜ν•΄μ„œ 수슡될 수 μžˆλŠ” λ‹€μ†Œ λ―Έμ•½ν•œ 였λ₯˜

μ˜ˆμ™Έ 클래슀의 계측ꡬ쑰

  • λͺ¨λ“  μ˜ˆμ™Έμ˜ 졜고 쑰상은 Exception 클래슀
    • Exception ν΄λž˜μŠ€μ™€ κ·Έ μžμ†λ“€ (μ‚¬μš©μžμ˜ μ‹€μˆ˜μ™€ 같은 외적인 μš”μΈμœΌλ‘œ λ°œμƒ)
    • RuntimeException ν΄λž˜μŠ€μ™€ κ·Έ μžμ†λ“€ (주둜 ν”„λ‘œκ·Έλž˜λ¨Έμ˜ μ‹€μˆ˜λ‘œ λ°œμƒ)
    • Exception 클래슀의 μžμ†λ“€μ„ μ΄λ ‡κ²Œ 두 그룹으둜 λ‚˜λˆŒ 수 있음

μ˜ˆμ™Έμ²˜λ¦¬ν•˜κΈ° - try-catchλ¬Έ

  • μ •μ˜ : ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ μ‹œ λ°œμƒν•  수 μžˆλŠ” μ˜ˆμ™Έμ— λŒ€ν•œ μ½”λ“œλ₯Ό μž‘μ„±
  • λͺ©μ  : ν”„λ‘œκ·Έλž¨μ˜ 비정상 μ’…λ£Œλ₯Ό 막고 정상적인 μ‹€ν–‰μƒνƒœλ₯Ό μœ μ§€ν•˜κΈ° μœ„ν•΄
  • λ°œμƒν•œ μ˜ˆμ™Έλ₯Ό μ²˜λ¦¬ν•˜μ§€ λͺ»ν•˜λ©΄ ν”„λ‘œκ·Έλž¨μ΄ λΉ„μ •μƒμ μœΌλ‘œ μ’…λ£Œλ˜λ©° JVM의 μ˜ˆμ™Έ μ²˜λ¦¬κΈ°κ°€ λ°›μ•„μ„œ μ˜ˆμ™Έμ˜ 원인을 좜λ ₯ν•΄ 쀌
  • ꡬ쑰
    • ν•˜λ‚˜μ˜ try λΈ”λŸ­ λ‹€μŒμ—λŠ” ν•˜λ‚˜ μ΄μƒμ˜ catch λΈ”λŸ­
    • catch λΈ”λŸ­κ³Ό μΌμΉ˜ν•˜λŠ” μ˜ˆμ™Έμ˜ μ’…λ₯˜κ°€ 아닐 μ‹œ μ˜ˆμ™Έ 처리 X
    • catch λΈ”λŸ­ 내에 또 try-catchλ₯Ό λ§Œλ“€ 경우 같은 μ΄λ¦„μ˜ μ°Έμ‘° λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ μ•ˆ 됨

try-catchλ¬Έμ—μ„œμ˜ 흐름

  • try λΈ”λŸ­ λ‚΄μ—μ„œ μ˜ˆμ™Έκ°€ λ°œμƒν•œ 경우
    • μΌμΉ˜ν•˜λŠ” catch λΈ”λŸ­μ„ 찾음
    • μΌμΉ˜ν•˜λŠ” catch λΈ”λŸ­μ„ 찾으면 catch λΈ”λŸ­ λ‚΄μ˜ λ¬Έμž₯ μˆ˜ν–‰ ν›„ 전체 try-catch λΉ μ Έλ‚˜κ°„ λ’€ κ·Έλ‹€μŒ λ¬Έμž₯ μˆ˜ν–‰
    • μΌμΉ˜ν•˜λŠ” catch λΈ”λŸ­μ„ λͺ» 찾으면 μ˜ˆμ™ΈλŠ” μ²˜λ¦¬λ˜μ§€ λͺ»ν•¨
  • try λΈ”λŸ­ λ‚΄μ—μ„œ μ˜ˆμ™Έκ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ” 경우
    • catch λΈ”λŸ­μ„ κ±°μΉ˜μ§€ μ•Šκ³  전체 try-catch λΉ μ Έλ‚˜κ°„ λ’€ κ·Έλ‹€μŒ λ¬Έμž₯ μˆ˜ν–‰

μ˜ˆμ™Έμ˜ λ°œμƒκ³Ό catch λΈ”λŸ­

  • μ˜ˆμ™Έκ°€ λ°œμƒν•˜λ©΄ λ°œμƒν•œ μ˜ˆμ™Έμ— ν•΄λ‹Ήν•˜λŠ” 클래슀의 μΈμŠ€ν„΄μŠ€κ°€ 생성됨
  • 첫 번째 catchλΆ€ν„° λ‚΄λ €κ°€λ©΄μ„œ κ΄„ν˜Έ 내에 μ„ μ–Έλœ μ°Έμ‘° λ³€μˆ˜μ˜ μ’…λ₯˜μ™€ μ˜ˆμ™Έ 클래슀 μΈμŠ€ν„΄μŠ€ 확인
  • κ²€μ‚¬λŠ” instanceof μ—°μ‚°μžλ₯Ό 이용
  • Exception 클래슀λ₯Ό catch에 μ„ μ–Έν•˜λ©΄ λͺ¨λ“  μ˜ˆμ™Έλ₯Ό 처리 κ°€λŠ₯
  • μ˜ˆμ™Έκ°€ λ°œμƒν–ˆμ„ λ•Œ μ˜ˆμ™Έ 클래슀의 μΈμŠ€ν„΄μŠ€μ—μ„œ getMessage() λ©”μ†Œλ“œλŠ” λ°œμƒν•œ μ˜ˆμ™Έ 클래슀의 μΈμŠ€ν„΄μŠ€μ— μ €μž₯된 메세지λ₯Ό 얻을 수 있음
  • μ˜ˆμ™Έκ°€ λ°œμƒν–ˆμ„ λ•Œ μ˜ˆμ™Έ 클래슀의 μΈμŠ€ν„΄μŠ€μ—μ„œ printStachTrace() λ©”μ„œλ“œλŠ” μ˜ˆμ™Έ λ°œμƒ λ‹Ήμ‹œμ˜ 호좜 μŠ€νƒμ— μžˆμ—ˆλ˜ λ©”μ„œλ“œμ˜ 정보와 μ˜ˆμ™Έ 메세지λ₯Ό 화면에 좜λ ₯
  • JDK 1.7λΆ€ν„° '|' 기호λ₯Ό μ‚¬μš©ν•΄ μ—¬λŸ¬ catch λΈ”λŸ­μ„ ν•˜λ‚˜λ‘œ ν•©μΉ  수 μžˆλŠ” λ©€ν‹° catch λΈ”λŸ­μ„ 지원
    • μ˜ˆμ™Έ 클래슀의 κ°œμˆ˜μ—λŠ” μ œν•œ X
    • 두 μ˜ˆμ™Έ ν΄λž˜μŠ€κ°€ 쑰상과 μžμ†μ˜ 관계일 μ‹œ λΆˆν•„μš”ν•œ μ½”λ“œλ₯Ό μ œκ±°ν•˜λΌλŠ” 의미의 μ—λŸ¬ λ°œμƒ
    • λ©€ν‹° catch λΈ”λŸ­μ—μ„œ μ˜ˆμ™Έκ°€ 처리되면 μ‹€μ œλ‘œ μ–΄λ–€ μ˜ˆμ™Έκ°€ λ°œμƒν–ˆλŠ”μ§€ μ•Œ 수 μ—†μŒ (μ°Έμ‘° λ³€μˆ˜ eλŠ” μ—°κ²°λœ μ˜ˆμ™Έ ν΄λž˜μŠ€λ“€μ˜ 곡톡뢄λͺ¨μΈ 쑰상 μ˜ˆμ™Έ ν΄λž˜μŠ€μ— μ„ μ–Έλœ λ©€λ²„λ§Œ μ‚¬μš© κ°€λŠ₯)
    • μ°Έμ‘° λ³€μˆ˜ eλŠ” μƒμˆ˜μ΄λ―€λ‘œ 값을 λ³€κ²½ λΆˆκ°€λŠ₯

μ˜ˆμ™Έ λ°œμƒμ‹œν‚€κΈ°

  • ν‚€μ›Œλ“œ throwλ₯Ό μ‚¬μš©ν•΄μ„œ ν”„λ‘œκ·Έλž˜λ¨Έκ°€ 고의적으둜 μ˜ˆμ™Έ λ°œμƒ κ°€λŠ₯
  • μ—°μ‚°μž newλ₯Ό μ΄μš©ν•΄μ„œ μ˜ˆμ™Έ 클래슀의 객체λ₯Ό λ§Œλ“  λ’€ throw
  • Exception ν΄λž˜μŠ€λ“€μ€ λ°œμƒν•  κ°€λŠ₯성이 μžˆλŠ” λͺ¨λ“  λ¬Έμž₯듀에 λŒ€ν•΄ μ˜ˆμ™Έμ²˜λ¦¬λ₯Ό ν•΄μ€˜μ•Ό 함 (컴파일 λ˜μ§€ μ•ŠμŒ)
    • RuntimeException의 μžμ† ν΄λž˜μŠ€λ“€μ€ 컴파일 κ°€λŠ₯, μ˜ˆμ™Έμ²˜λ¦¬λ₯Ό κ°•μ œν•˜μ§€ μ•ŠλŠ”λ‹€. (unchecked μ˜ˆμ™Έ)

λ©”μ„œλ“œμ— μ˜ˆμ™Έ μ„ μ–Έν•˜κΈ°

  • ν‚€μ›Œλ“œ throwsλ₯Ό μ‚¬μš©ν•΄μ„œ λ©”μ„œλ“œ λ‚΄μ—μ„œ λ°œμƒν•  수 μžˆλŠ” μ˜ˆμ™Έλ₯Ό μ„ μ–Έ κ°€λŠ₯
  • λ©”μ„œλ“œμ— λ°œμƒ κ°€λŠ₯ν•œ μ˜ˆμ™Έλ₯Ό λͺ…μ‹œν•˜μ—¬ κ²¬κ³ ν•œ ν”„λ‘œκ·Έλž¨ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ„λ‘ λ„μ™€μ€Œ
  • λ©”μ„œλ“œμ— μ˜ˆμ™Έλ₯Ό μ„ μ–Έν•  λ•Œ 일반적으둜 RuntimeException 클래슀λ₯Ό 적지 μ•ŠμŒ
    • 보톡 λ°˜λ“œμ‹œ μ²˜λ¦¬ν•΄ μ£Όμ–΄μ•Ό ν•˜λŠ” μ˜ˆμ™Έλ“€λ§Œ μ„ μ–Έ
  • λ©”μ„œλ“œμ˜ throws에 μ˜ˆμ™Έλ₯Ό λͺ…μ‹œν•˜λŠ” 것은 ν˜ΈμΆœν•œ λ©”μ„œλ“œμ—κ²Œ μ˜ˆμ™Έλ₯Ό μ „λ‹¬ν•˜μ—¬ λ– λ§‘κΈ°λŠ” 것을 의미
    • λ°˜λ“œμ‹œ μ–΄λ””μ„ κ°€λŠ” 처리λ₯Ό ν•΄μ£Όμ–΄μ•Ό 함

finally λΈ”λŸ­

  • μ˜ˆμ™Έμ˜ λ°œμƒ 여뢀에 상관없이 μ‹€ν–‰λ˜μ–΄μ•Ό ν•  μ½”λ“œλ₯Ό ν¬ν•¨μ‹œν‚΄
  • try-catch 문의 끝에 μ„ νƒμ μœΌλ‘œ 덧뢙여 μ‚¬μš©
  • try와 catch에 μ€‘λ³΅λ˜λŠ” λ‚΄μš©μ΄ μžˆλ‹€λ©΄ finally λΈ”λŸ­μ— ν¬ν•¨μ‹œν‚¬ 것
  • try λΈ”λŸ­μ—μ„œ return 문이 μ‹€ν–‰λ˜λŠ” κ²½μš°μ—λ„ finally λΈ”λŸ­μ˜ λ¬Έμž₯듀이 λ¨Όμ € μ‹€ν–‰λœ 후에 ν˜„μž¬ μ‹€ν–‰ 쀑인 λ©”μ„œλ“œλ₯Ό μ’…λ£Œ
    • catch λΈ”λŸ­μ—μ„œ return 문을 λ§Œλ‚¬μ„ λ•Œλ„ λ§ˆμ°¬κ°€μ§€

μžλ™ μžμ› λ°˜ν™˜ - try-with-resources λ¬Έ

  • JDK1.7λΆ€ν„° μΆ”κ°€λœ try-catch 문의 λ³€ν˜•
  • 주둜 μž…μΆœλ ₯에 κ΄€λ ¨λœ κ΅¬λ¬Έμ—μ„œ 유용
    • μ‚¬μš©ν•œ 후에 μžμ›μ„ λ°˜ν™˜ν•΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— λ°˜λ“œμ‹œ μ’…λ£Œν•΄ μ€˜μ•Ό ν•˜λŠ” ν΄λž˜μŠ€λ“€
  • try κ΄„ν˜Έ μ•ˆμ— 객체λ₯Ό μƒμ„±ν•˜λŠ” λ¬Έμž₯을 λ„£λŠ” 방식
    • 두 λ¬Έμž₯ 이상 넣을 μ‹œ ';'둜 ꡬ뢄
  • λ”°λ‘œ close()λ₯Ό ν˜ΈμΆœν•˜μ§€ μ•Šμ•„λ„ try λΈ”λŸ­μ„ λ²—μ–΄λ‚˜λŠ” μˆœκ°„ μžλ™μ μœΌλ‘œ close() 호좜
  • close() 호좜 ν›„ catch λ˜λŠ” finally λΈ”λŸ­μ΄ μˆ˜ν–‰
  • μžλ™μœΌλ‘œ close()κ°€ 호좜될 수 있으렀면 AutoCloseableμ΄λΌλŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ κ²ƒμ΄μ–΄μ•Όλ§Œ 함
  • λ§Œμ•½ close()μ—μ„œ μ˜ˆμ™Έκ°€ λ°œμƒν–ˆμ„ μ‹œ μ–΅μ œλœ(suppressed)λΌλŠ” 의미의 머리말과 ν•¨κ»˜ 좜λ ₯
    • Throwable의 void addSuppressed(Throwable exception) λ©”μ†Œλ“œλ‘œ μ–΅μ œλœ μ˜ˆμ™Έλ₯Ό μΆ”κ°€ κ°€λŠ₯
    • Throwable의 Throwable[] getSuppressed()둜 μ–΅μ œλœ μ˜ˆμ™Έλ₯Ό λ°˜ν™˜

μ‚¬μš©μž μ •μ˜ μ˜ˆμ™Έ λ§Œλ“€κΈ°

  • 보톡 Exception 클래슀 λ˜λŠ” RuntimeException ν΄λž˜μŠ€λ‘œλΆ€ν„° 상속받아 클래슀λ₯Ό λ§Œλ“¦
    • ν•„μš”μ— 따라 μ•Œλ§žμ€ μ˜ˆμ™Έ 클래슀λ₯Ό 선택 κ°€λŠ₯
  • ν•„μš”ν•˜λ‹€λ©΄ 멀버 λ³€μˆ˜λ‚˜ λ©”μ„œλ“œλ₯Ό μΆ”κ°€ κ°€λŠ₯
    • λ©”μ‹œμ§€, μ—λŸ¬μ½”λ“œ κ°’ 등등을 μΆ”κ°€ν•˜μ—¬ getMessage()둜 μ‘°νšŒν•  수 μžˆλ„λ‘ κ΅¬ν˜„ κ°€λŠ₯
  • super(msg)둜 String을 λ§€κ°œλ³€μˆ˜λ‘œ λ°›λŠ” μƒμ„±μžλ₯Ό μΆ”κ°€ κ°€λŠ₯
  • κΈ°μ‘΄μ—λŠ” 주둜 Exception을 μƒμ†λ°›μ•„μ„œ checked μ˜ˆμ™Έλ‘œ μž‘μ„±ν•˜λŠ” κ²½μš°κ°€ λ§Žμ•˜μ§€λ§Œ μš”μ¦˜μ€ μ˜ˆμ™Έ 처리λ₯Ό μ„ νƒμ μœΌλ‘œ ν•  수 μžˆλ„λ‘ RuntimeException을 μƒμ†λ°›μ•„μ„œ μž‘μ„±ν•˜λŠ” μͺ½μœΌλ‘œ λ°”λ€Œκ³  있음
    • checked μ˜ˆμ™ΈλŠ” λΆˆν•„μš”ν•œ κ²½μš°μ—λ„ try-catch문을 λ„£μ–΄μ€˜μ•Ό ν•˜κΈ° λ•Œλ¬Έ

μ˜ˆμ™Έ λ‚΄λ˜μ§€κΈ°(exception re-throwing)

  • ν•œ λ©”μ„œλ“œμ—μ„œ λ°œμƒν•  수 μžˆλŠ” μ˜ˆμ™Έκ°€ μ—¬λŸΏμΌ λ•Œ λͺ‡ κ°œλŠ” 선언뢀에 지정(throwλ¬Έ), λͺ‡ κ°œλŠ” try-catch 문으둜 직접 μ²˜λ¦¬ν•˜λŠ” 방법도 κ°€λŠ₯
  • 단 ν•˜λ‚˜μ˜ μ˜ˆμ™Έμ— λŒ€ν•΄μ„œλ„ μ–‘μͺ½μ—μ„œ μ²˜λ¦¬ν•˜λ„λ‘ λ‚˜λˆŒ 수 있음
  • μ˜ˆμ™Έ λ‚΄λ˜μ§€κΈ°λž€ μ˜ˆμ™Έλ₯Ό μ²˜λ¦¬ν•œ 후에 μΈμœ„μ μœΌλ‘œ λ‹€μ‹œ λ°œμƒμ‹œν‚€λŠ” 것
  • μ˜ˆμ™Έ λ˜μ§€κΈ°λ₯Ό μœ„ν•΄ throw둜 μ˜ˆμ™Έλ₯Ό ν˜ΈμΆœν•œ λ©”μ„œλ“œ μͺ½μ— μ „λ‹¬ν•˜λ©΄ catch λΈ”λŸ­μ—μ„œ return 문이 ν•„μš”ν•˜μ§€ μ•ŠμŒ

μ—°κ²°λœ μ˜ˆμ™Έ(chained exception)

  • μ˜ˆμ™Έ Aκ°€ μ˜ˆμ™Έ Bλ₯Ό λ°œμƒμ‹œμΌ°λ‹€λ©΄, Aλ₯Ό B의 원인 μ˜ˆμ™ΈλΌκ³  뢀름
  • μ˜ˆμ™Έλ₯Ό μƒμ„±ν•œ 후에 initCause()둜 원인 μ˜ˆμ™Έλ₯Ό λ“±λ‘ν•˜κ³  throw둜 μ˜ˆμ™Έλ₯Ό 던짐
  • initCause()λŠ” Exception 클래슀의 쑰상인 Throwable ν΄λž˜μŠ€μ— μ •μ˜λœ κ²ƒμœΌλ‘œ λͺ¨λ“  μ˜ˆμ™Έμ—μ„œ μ‚¬μš© κ°€λŠ₯
    • Throwable initCause(Throwable cause) : μ§€μ •λœ μ˜ˆμ™Έλ₯Ό 원인 μ˜ˆμ™Έλ‘œ 등둝 (Throwable κ΅¬ν˜„μ—μ„  객체 μžμ‹ μ„ 원인 μ˜ˆμ™Έλ‘œ 등둝)
    • Throwable getCause() : 원인 μ˜ˆμ™Έλ₯Ό λ°˜ν™˜
  • μ—¬λŸ¬ 가지 μ˜ˆμ™Έλ₯Ό ν•˜λ‚˜μ˜ 큰 λΆ„λ₯˜μ˜ μ˜ˆμ™Έλ‘œ λ¬Άμ–΄μ„œ 닀루기 μœ„ν•΄ μ—°κ²°λœ μ˜ˆμ™Έλ₯Ό μ‚¬μš©
    • λ°œμƒμ‹œν‚¨ μ˜ˆμ™Έμ˜ 쑰상 클래슀둜 지정 ν›„ κ΅¬ν˜„ μ‹œ μ‹€μ œλ‘œ λ°œμƒν•œ μ˜ˆμ™Έλ₯Ό μ•Œ 수 μ—†λŠ” 문제λ₯Ό ν•΄κ²°ν•˜κ³  상속관계λ₯Ό λ³€κ²½ν•˜λŠ” 뢀담을 μ€„μž„
    • μ„œλ‘œ 상속관계가 μ•„λ‹ˆμ–΄λ„ μƒκ΄€μ—†μŒ
  • checked μ˜ˆμ™Έλ₯Ό unchecked μ˜ˆμ™Έλ‘œ κ°μ‹ΈλŠ” 방법(μƒμ„±μžμ˜ λ§€κ°œλ³€μˆ˜λ‘œ μ˜ˆμ™Έ μΈμŠ€ν„΄μŠ€λ₯Ό λ„£μœΌλ©΄ 원인 μ˜ˆμ™Έλ‘œ 등둝됨)μœΌλ‘œλ„ 많이 μ‚¬μš©λ¨