[Java] ์˜ˆ์™ธ(Exception), ์˜ˆ์™ธ ์ฒ˜๋ฆฌ(Exception Handling)

๐Ÿ”น ์˜ˆ์™ธ(Exception)๋ž€ ?

  • ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์ค‘ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ƒํ™ฉ์„ ์˜๋ฏธํ•œ๋‹ค.
  • ์ด๋Š” ์ •์ƒ์ ์ธ ๋ช…๋ น ํ๋ฆ„์„ ๋ฐฉํ•ดํ•˜๋Š” ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜์ด๋ฉฐ, ๋‹จ์ˆœํ•œ ๋ฌธ๋ฒ• ์˜ค๋ฅ˜(Syntax Error)์™€๋Š” ๋‹ค๋ฅด๋‹ค.

[ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ ์‚ฌ๋ก€ ]

  • 0์œผ๋กœ ๋‚˜๋ˆ„๊ธฐ →  ArithmeticException
  • ๋ฐฐ์—ด์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ์ ‘๊ทผ → ArrayIndexOutOfBoundsException
  • ์ž˜๋ชป๋œ ๊ฐ์ฒด ์ฐธ์กฐ (Null ๊ฐ’ ์ฐธ์กฐ) → NullPointerException

 

๐Ÿ”น ์˜ˆ์™ธ ์ฒ˜๋ฆฌ(Exception Handling)๋ž€ ?

  • ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ, ํ”„๋กœ๊ทธ๋žจ์ด ๊ฐ‘์ž๊ธฐ ์ข…๋ฃŒ๋˜์ง€ ์•Š๋„๋ก ํ•˜๊ณ , ์ ์ ˆํ•œ ๋Œ€์ฒ˜๋ฅผ ํ†ตํ•ด ์ •์ƒ์ ์ธ ํ๋ฆ„์„ ์œ ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

[ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ์ด์œ  ]

  • ํ”„๋กœ๊ทธ๋žจ์˜ ์•ˆ์ •์„ฑ ์œ ์ง€ (๊ฐ‘์ž‘์Šค๋Ÿฌ์šด ์ข…๋ฃŒ ๋ฐฉ์ง€)
  • ์˜ค๋ฅ˜์˜ ์›์ธ ํŒŒ์•… ๋ฐ ๋Œ€์‘ ๊ฐ€๋Šฅ
  • ์‚ฌ์šฉ์ž์—๊ฒŒ ์ ์ ˆํ•œ ํ”ผ๋“œ๋ฐฑ ์ œ๊ณต

 

๐Ÿ”ธ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•

โ—ฝ try-catch ๋ธ”๋ก ์‚ฌ์šฉ

try {
    int result = 10 / 0; // ์˜ˆ์™ธ ๋ฐœ์ƒ (ArithmeticException)
} catch (ArithmeticException e) {
    System.out.println("0์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
}

โ—ฝ throws ํ‚ค์›Œ๋“œ ์‚ฌ์šฉ - ์˜ˆ์™ธ ์œ„์ž„

public void readFile() throws IOException {
    FileReader file = new FileReader("test.txt");
}

โ—ฝ finally ๋ธ”๋ก ์‚ฌ์šฉ - ์ž์› ์ •๋ฆฌ ๋“ฑ ํ•„์ˆ˜ ์ž‘์—… ์ˆ˜ํ–‰

try {
    FileReader file = new FileReader("test.txt");
} catch (IOException e) {
    System.out.println("ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
} finally {
    System.out.println("์˜ˆ์™ธ ๋ฐœ์ƒ ์—ฌ๋ถ€์™€ ๊ด€๊ณ„์—†์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.");
}

 

๐Ÿ”น ์ž๋ฐ”์—์„œ์˜ Exception classes ๊ณ„์ธต ๊ตฌ์กฐ

 

์ถœ์ฒ˜ - https://simplesnippets.tech/exception-handling-in-java-part-1/

 

์ž๋ฐ”์—์„œ์˜ ๋ชจ๋“  ์˜ˆ์™ธ ๋ฐ ์˜ค๋ฅ˜ ์œ ํ˜•์€ Throwable ํด๋ž˜์Šค์˜ ํ•˜์œ„ ํด๋ž˜์Šค๋กœ ๋ถ„๋ฅ˜๋œ๋‹ค.

์ด๋Š” ํฌ๊ฒŒ ์˜ค๋ฅ˜(Error), ๊ฒ€์‚ฌ ์˜ˆ์™ธ(Checked Exception), ๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ(Unchecked Exception) ์„ธ ๊ฐ€์ง€ ์œ ํ˜•์œผ๋กœ ๋‚˜๋‰œ๋‹ค.

 

๐Ÿ”ธ ์˜ค๋ฅ˜(Error)

  • ์‹œ์Šคํ…œ์—์„œ ๋น„์ •์ƒ์ ์ธ ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ์—์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†๋Š” ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ
  • ์‹œ์Šคํ…œ ๋ ˆ๋ฒจ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋กœ, ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋กœ ํ•ด๊ฒฐํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Œ

[ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ ]

  • OutOfMemoryError → ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ
  • StackOverflowError → ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ

 

๐Ÿ”ธ ๊ฒ€์‚ฌ ์˜ˆ์™ธ(Checked Exception)

  • ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ๊ฒ€์‚ฌ๋˜๋Š” ์˜ˆ์™ธ (์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ•์ œํ•จ)
  • ๋ฐ˜๋“œ์‹œ try-catch๋กœ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜ throws๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•จ
  • ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š์œผ๋ฉด ์ปดํŒŒ์ผ ์˜ค๋ฅ˜ ๋ฐœ์ƒ

[ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ ]

  • ClassNotFoundException → ํด๋ž˜์Šค ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†์Œ
  • IOException → ์ž…์ถœ๋ ฅ ๊ด€๋ จ ์˜ˆ์™ธ
  • SQLException → ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ จ ์˜ˆ์™ธ

 

๐Ÿ”ธ ๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ(Unchecked Exception)

  • ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ๊ฒ€์‚ฌ๋˜์ง€ ์•Š์œผ๋ฉฐ, ์‹คํ–‰ ์ค‘(Runtime) ๋ฐœ์ƒ
  • ๋ช…์‹œ์ ์ธ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์ˆ˜๊ฐ€ ์•„๋‹˜
  • ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ”๋“œ์—์„œ ์ง์ ‘ ๋ฐฉ์ง€ํ•ด์•ผ ํ•˜๋Š” ์˜ˆ์™ธ

[ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ ]

  • NullPointerException → ๋„ ๊ฐ’ ์ฐธ์กฐ
  • IndexOutOfBoundsException → ๋ฐฐ์—ด ๋˜๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ์ ‘๊ทผ
  • ArithmeticException → 0์œผ๋กœ ๋‚˜๋ˆ„๊ธฐ

 

๐Ÿ”น ์ž๋ฐ”์—์„œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ 9๊ฐ€์ง€ Best Practices

1๏ธโƒฃ finally ๋ธ”๋ก ๋˜๋Š” try-with-resources ์‚ฌ์šฉ

  • ํŒŒ์ผ, ๋„คํŠธ์›Œํฌ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ๋“ฑ์˜ ์ž์›์€ ๋ฐ˜๋“œ์‹œ ํ•ด์ œํ•ด์•ผ ํ•œ๋‹ค.
  • Java 7 ์ด์ƒ์—์„œ๋Š” try-with-resources ๊ตฌ๋ฌธ์„ ํ™œ์šฉํ•˜์—ฌ ์ž๋™์œผ๋กœ ์ž์›์„ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

2๏ธโƒฃ ๊ตฌ์ฒด์ ์ธ ์˜ˆ์™ธ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌ

  • Exception์ด๋‚˜ Throwable๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ณด๋‹ค ๊ตฌ์ฒด์ ์ธ ์˜ˆ์™ธ ํƒ€์ž…์„ ์‚ฌ์šฉํ•œ๋‹ค.

 

3๏ธโƒฃ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ˆ์™ธ๋ฅผ JavaDoc์œผ๋กœ ๋ฌธ์„œํ™”

  • throws ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, JavaDoc ์ฃผ์„์— ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ˆ์™ธ ์ •๋ณด๋ฅผ ๋ช…ํ™•ํžˆ ๊ธฐ์žฌํ•œ๋‹ค.

 

4๏ธโƒฃ ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ์„ค๋ช… ๋ฉ”์‹œ์ง€ ์ถ”๊ฐ€

  • ์˜ˆ์™ธ๋ฅผ ๋˜์งˆ ๋•Œ, ๋ช…ํ™•ํ•œ ์˜ค๋ฅ˜๋ฅผ ํฌํ•จํ•˜์—ฌ ๋””๋ฒ„๊น…์„ ์‰ฝ๊ฒŒ ๋งŒ๋“ ๋‹ค.
throw new IllegalArgumentException("์ž…๋ ฅ ๊ฐ’์ด ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค: " + value);

 

5๏ธโƒฃ catch๋ฌธ์—์„œ ๊ฐ€์žฅ ๊ตฌ์ฒด์ ์ธ ์˜ˆ์™ธ๋ถ€ํ„ฐ ์ฒ˜๋ฆฌ

  • ๊ตฌ์ฒด์ ์ธ ์˜ˆ์™ธ๋ฅผ ๋จผ์ € ์ฒ˜๋ฆฌํ•˜๊ณ , ๋” ํฌ๊ด„์ ์ธ ์˜ˆ์™ธ๋ฅผ ๋‚˜์ค‘์— ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.
try {
    ...
} catch (IOException e) {  // ๊ตฌ์ฒด์ ์ธ ์˜ˆ์™ธ ๋จผ์ €
    ...
} catch (Exception e) {  // ๋ฒ”์šฉ์ ์ธ ์˜ˆ์™ธ ๋‚˜์ค‘์—
    ...
}

 

6๏ธโƒฃ Throwable์„ ์žก์ง€ ์•Š๋Š”๋‹ค. (Exception ๋˜๋Š” RuntimeException ์‚ฌ์šฉ)

  • Throwable์„ ์žก์œผ๋ฉด Error(์˜ˆ: OutOfMemoryError, StackOverflowError)๊นŒ์ง€ ํฌ๊ด„ํ•˜๊ฒŒ ๋˜์–ด ๋น„์ •์ƒ์ ์ธ ์ƒํ™ฉ์—์„œ๋„ ํ”„๋กœ๊ทธ๋žจ์ด ๊ณ„์† ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋‹ค.
  • ๋Œ€์‹ ,  Exception ๋˜๋Š” RuntimeException์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.

 

7๏ธโƒฃ ์˜ˆ์™ธ๋ฅผ ๋ฌด์‹œํ•˜์ง€ ์•Š๋Š”๋‹ค. (์ ์ ˆํ•œ ๋กœ๊น… ์ˆ˜ํ–‰)

  • ์˜ˆ์™ธ๋ฅผ ์žก๊ณ ๋„ ์•„๋ฌด ์กฐ์น˜ ์—†์ด ๋ฌด์‹œํ•˜๋ฉด ๋ฌธ์ œ ํŒŒ์•…์ด ์–ด๋ ค์›Œ์ง„๋‹ค.
  • ์ตœ์†Œํ•œ ๋กœ๊น…(logging)์ด๋‚˜ ์ ์ ˆํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค.
try {
    ...
} catch (IOException e) {
    System.err.println("ํŒŒ์ผ์„ ์ฝ๋Š” ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: " + e.getMessage()); // ์ตœ์†Œํ•œ์˜ ๋กœ๊ทธ ์ถœ๋ ฅ
}

 

8๏ธโƒฃ ์ค‘๋ณต ๋กœ๊ทธ๋ฅผ ํ”ผํ•˜๊ณ  ์˜ˆ์™ธ๋ฅผ ๋‹ค์‹œ ๋˜์ง€์ง€ ์•Š๋Š”๋‹ค.

  • ์˜ˆ์™ธ๋ฅผ ์žก๊ณ  ๋กœ๊น…ํ•œ ํ›„ ๋‹ค์‹œ ๋˜์ง€๋ฉด ์ค‘๋ณต ๋กœ๊ทธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์˜ˆ์™ธ๋ฅผ ํ•œ ๊ณณ์—์„œ๋งŒ ๋กœ๊น…ํ•˜๊ฑฐ๋‚˜, ์ฒ˜๋ฆฌํ•  ๊ณณ์—์„œ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•œ๋‹ค.

 

9๏ธโƒฃ ๋ถˆํ•„์š”ํ•œ ์˜ˆ์™ธ ๊ฐ์‹ธ๊ธฐ๋ฅผ ํ”ผํ•˜๊ณ  ์›๋ž˜ ์˜ˆ์™ธ ์ •๋ณด๋ฅผ ๋ณด์กด

  • ์˜ˆ์™ธ๋ฅผ ๊ฐ์Œ€ ๋•Œ ์›๋ž˜ ์˜ˆ์™ธ ์ •๋ณด(e.getCause())๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค.
try {
    ...
} catch (IOException e) {
    throw new RuntimeException("ํŒŒ์ผ ์ฒ˜๋ฆฌ ์ค‘ ์˜ˆ์™ธ ๋ฐœ์ƒ", e); // ์›๋ณธ ์˜ˆ์™ธ ํฌํ•จ
}

 

 

 

 

 

๐Ÿ“ƒ reference