item 71 leekyunghee - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

ํ•„์š” ์—†๋Š” ๊ฒ€์‚ฌ ์˜ˆ์™ธ ์‚ฌ์šฉ์€ ํ”ผํ•˜๋ผ

๊ฒ€์‚ฌ ์˜ˆ์™ธ ํšŒํ”ผ ๋ฐฉ๋ฒ•

1. ๋น„๊ฒ€์‚ฌ ์˜ˆ์™ธ

  • API๋ฅผ ์ œ๋Œ€๋กœ ์‚ฌ์šฉํ•ด๋„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ˆ์™ธ์ด๊ฑฐ๋‚˜ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์˜๋ฏธ ์žˆ๋Š” ์กฐ์น˜๋ฅผ ์ทจํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ์ด ์ •๋„ ๋ถ€๋‹ด์ฏค์€ ๋ฐ›์•„๋“ค์ผ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.
  • ํ•˜์ง€๋งŒ ์ด ๊ฒฝ์šฐ๋“ค์ด ์•„๋‹ˆ๋ผ๋ฉด ๋น„๊ฒ€์‚ฌ ์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. (item70)

์•„๋ž˜ ๋‘ ์ฝ”๋“œ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ(API ์‚ฌ์šฉ์ž)๊ฐ€ ๊ฒ€์‚ฌ ์˜ˆ์™ธ๋ฅผ ์ฑ…์ž„์ง€๋Š” ์‚ฌ๋ก€๋‹ค.

// ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋น„๊ฒ€์‚ฌ ์˜ˆ์™ธ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํ•ด๊ฒฐ
} catch (TheCheckedException e) { 
    throw new AssertionError();  

}
// ์—๋Ÿฌ ์Šคํƒ ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์‹œ์Šคํ…œ์„ ์ข…๋ฃŒ์‹œํ‚จ๋‹ค.
} catch (TheCheckedException e) {
    e.printStackTrace();
    System.exit(1);
}

๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ ์• ์ดˆ์— ๋น„๊ฒ€์‚ฌ ์˜ˆ์™ธ๋กœ API๋ฅผ ๋งŒ๋“ค๋ฉด ๋์„ ๊ฒƒ์ด๋‹ค.

2. Optional

  • ๊ฒ€์‚ฌ ์˜ˆ์™ธ๋ฅผ ํšŒํ”ผํ•˜๋Š” ๋‘ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ ์ ์ ˆํ•œ ๊ฒฐ๊ณผ ํƒ€์ž…์„ ๋‹ด์€ ์˜ต์…”๋„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. (item55) ๊ฒ€์‚ฌ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ๋Œ€์‹  ๋‹จ์ˆœํžˆ ๋นˆ ์˜ต์…”๋„์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋œ๋‹ค.
  • ํ•˜์ง€๋งŒ ์ด ๋ฐฉ์‹์€ ๋‹จ์ ์ด ์žˆ๋‹ค. ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ ์ด์œ ๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ๋ถ€๊ฐ€ ์ •๋ณด๋ฅผ ๋‹ด์„ ์ˆ˜ ์—†๋‹ค๋Š” ์ ์ด๋‹ค. (์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ตฌ์ฒด์ ์ธ ์˜ˆ์™ธ ํƒ€์ž…๊ณผ ๊ทธ ํƒ€์ž…์ด ์ œ๊ณตํ•˜๋Š” ๋ฉ”์„œ๋“œ๋“ค์„ ํ™œ์šฉํ•ด ๋ถ€๊ฐ€ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค.(item70))

3. ๋ฉ”์„œ๋“œ ์ชผ๊ฐœ๊ธฐ

  • ๊ฒ€์‚ฌ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ๋ฉ”์„œ๋“œ๋ฅผ 2๊ฐœ๋กœ ์ชผ๊ฐœ์–ด ๋น„๊ฒ€์‚ฌ ์˜ˆ์™ธ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด๋‹ค. ์ชผ๊ฐœ์ง„ ์ฒซ ๋ฒˆ์งธ ๋ฉ”์„œ๋“œ๋Š” ์˜ˆ์™ธ๊ฐ€ ๋˜์ ธ์งˆ์ง€ ์—ฌ๋ถ€๋ฅผ boolean๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
// ๋ฉ”์„œ๋“œ ์ชผ๊ฐœ๊ธฐ before

try {
    Obj.action(args);    
} catch (TheCheckedException e) {
    //do something
}

// ๋ฉ”์„œ๋“œ ์ชผ๊ฐœ๊ธฐ after
if (obj.actionPermitted(args)) {
    obj.action(args);
} else {
    //do something
}
  • action ๋‚ด์˜ ๋กœ์ง์„ 2๊ฐœ ๋งค์†Œ๋“œ (actionPermitted, action) ์œผ๋กœ ๋‚˜๋ˆˆ ๋ชจ์Šต์ด๋‹ค.
  • ๊น”๋”ํ•จ์„ ์–ด๋Š์ •๋„ ํฌ๊ธฐํ•˜๊ณ  ์œ ์—ฐํ•จ์„ ์–ป์—ˆ๋‹ค. ํ•œํŽธ actionPermitted๋Š” ์ƒํƒœ ๊ฒ€์‚ฌ ๋ฉ”์„œ๋“œ์— ํ•ด๋‹นํ•˜๋ฏ€๋กœ ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์ผ ํ•„์š”๊ฐ€ ์žˆ๋‹ค.
  • ์™ธ๋ถ€ ๋™๊ธฐํ™” ์—†์ด ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฑฐ๋‚˜ ์™ธ๋ถ€ ์š”์ธ์— ์˜ํ•ด ์ƒํƒœ๊ฐ€ ๋ณ€ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ด ๋ฆฌํŒฉํ„ฐ๋ง์€ ์ ์ ˆํ•˜์ง€ ์•Š๋‹ค. (item69)
  • actionPermitted์™€ action ํ˜ธ์ถœ ์‚ฌ์ด์— ๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ€ ๋ณ€ํ•  ์ˆ˜ ์žˆ๊ณ , ๋˜ ๋‘ ๋ฉ”์„œ๋“œ๊ฐ€ ๋™์ผํ•œ ๋กœ์ง์„ ์ค‘๋ณตํ•ด์„œ ๊ฐ€์ง€๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

ํ•ต์‹ฌ ์ •๋ฆฌ

  • ๊ผญ ํ•„์š”ํ•œ ๊ณณ์—๋งŒ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๊ฒ€์‚ฌ ์˜ˆ์™ธ๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ์•ˆ์ „์„ฑ์„ ๋†’์—ฌ์ฃผ์ง€๋งŒ ๋‚จ์šฉํ•˜๋ฉด ์“ฐ๊ธฐ ๊ณ ํ†ต์Šค๋Ÿฌ์šด API๋ฅผ ๋‚ณ๋Š”๋‹ค. API ํ˜ธ์ถœ์ž๊ฐ€ ์˜ˆ์™ธ ์ƒํ™ฉ์—์„œ
  • ๋ณต๊ตฌํ•  ๋ฐฉ๋ฒ•์ด ์—†๋‹ค๋ฉด ๋น„๊ฒ€์‚ฌ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€์ž. ๋ณต๊ตฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ณ  ํ˜ธ์ถœ์ž๊ฐ€ ๊ทธ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ๊ธธ ๋ฐ”๋ž€๋‹ค๋ฉด, ์˜ต์…”๋„ ์‚ฌ์šฉ์„ ๊ฒ€ํ† ํ•ด๋ณด์ž.
  • ๊ทธ๋ž˜๋„ ์—ฌ์˜์น˜ ์•Š์œผ๋ฉด ๊ทธ๋•Œ์„œ์•ผ ๊ฒ€์‚ฌ ์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•˜์ž.

image1

์ž๋ฐ”์—์„œ ์˜ˆ์™ธ๋Š” RuntimeException์„ ์ƒ์†ํ•˜์ง€ ์•Š๊ณ  ๊ผญ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” Checked Exception(๊ฒ€์‚ฌ ์˜ˆ์™ธ)๊ณผ ๋ฐ˜๋Œ€๋กœ ๋ช…์‹œ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์•„๋„ ๋˜๋Š” Unchecked Exception(๋น„ ๊ฒ€์‚ฌ ์˜ˆ์™ธ) ๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฒ€์‚ฌ ์˜ˆ์™ธ - ๋ฐœ์ƒํ•œ ๋ฌธ์ œ๋ฅผ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ฒ˜๋ฆฌํ•˜์—ฌ ์•ˆ์ •์„ฑ์„ ๋†’์ด๊ฒŒ๋” ํ•ด์ค€๋‹ค. ๊ฒ€์‚ฌ ์˜ˆ์™ธ๋ฅผ ๊ณผํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ์˜คํžˆ๋ ค ์“ฐ๊ธฐ ๋ถˆํŽธํ•œ API๊ฐ€ ๋œ๋‹ค.

  • ์–ด๋–ค ๋ฉ”์„œ๋“œ๊ฐ€ ๊ฒ€์‚ฌ ์˜ˆ์™ธ๋ฅผ ๋˜์งˆ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์„ ์–ธ๋๋‹ค๋ฉด ์ด๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ์—์„œ๋Š” catch ๋ธ”๋ก์„ ๋‘์–ด ๊ทธ ์˜ˆ์™ธ๋ฅผ ๋ถ™์žก์•„ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜ ๋” ๋ฐ”๊นฅ์œผ๋กœ ๋˜์ ธ ๋ฌธ์ œ๋ฅผ ์ „ํŒŒํ•ด์•ผ๋งŒ ํ•œ๋‹ค.
  • ๊ฒ€์‚ฌ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ๋ฉ”์„œ๋“œ๋Š” ์ŠคํŠธ๋ฆผ ์•ˆ์—์„œ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— (์•„์ดํ…œ 45-48) ์ž๋ฐ” 8๋ถ€ํ„ฐ๋Š” ๋ถ€๋‹ด์ด ๋”์šฑ ์ปค์กŒ๋‹ค.
public static void throwsException(int millisecond) throws IOException {
        
    File file = new File("/test.txt");
    // createNewFile()์—์„œ IOException์ด ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ํ•จ์ˆ˜ ์„ ์–ธ๋ถ€์— throws๋ฅผ ๋ช…์‹œํ•˜์˜€๋‹ค. 
    boolean b = file.createNewFile();    
  • ๋จผ์ € ์ด๋ ‡๊ฒŒ throws์— ๋ช…์‹œ๋ฅผ ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒƒ์— ๋Œ€ํ•œ ์ฐจ์ด๋ฅผ ์•Œ์•„๋ณด์ž.
  • ๋ช…์‹œ๋ฅผ ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ๊ฒ€์‚ฌ ์˜ˆ์™ธ ์ฆ‰ Checked Exception์ด๋‹ค. ๋ชฉ์ ์€ ํ•จ์ˆ˜ ์ˆ˜ํ–‰ ์ค‘์— ๋‚ ๋งŒํ•œ ์˜ˆ์™ธ์ด๋‹ˆ ํ˜ธ์ถœํ•˜๋Š” ์ธก์—์„œ๋Š” ์ด๋ฅผ ๋Œ€๋น„ํ•˜๋ผ.
  • ์ฆ‰ ์˜ˆ์™ธ๊ฐ€ ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌํ•˜๊ณ  ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ์กฐ์น˜ํ•˜๋ผ ์ด๋‹ค.
  • InterruptedException์ด ๊ทธ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์ด๋‹ค.

์•„๋ž˜ ์˜ˆ์ œ๋ฅผ ํ•ด์„ํ•ด๋ณด๋ฉด ์ด๋ ‡๋‹ค sleep() ํ•จ์ˆ˜๋Š” interrupt() ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ InterruptedException์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ๋Œ€๋น„ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

public static void sleep(int millisecond) {
    try {
        Thread.sleep(millisecond);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}
  • ์ด ์ฝ”๋“œ์™€ ๊ฐ™์ด ํ˜ธ์ถœ๋ถ€์—์„œ try - catch๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜์—์„œ throws ํ•ด์•ผ ํ•œ๋‹ค.
  • (throwsException ํ•จ์ˆ˜ ์˜ˆ์ œ์ฒ˜๋Ÿผ) ๊ทธ๋ ‡๋‹ค ์ด ์˜๋ฏธ๋Š” ํ˜ธ์ถœ๋ถ€์—์„œ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ  ์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ˜ธ์ถœ์ž์—๊ฒŒ ์ฑ…์ž„์„ ๋–  ๋„˜๊ธฐ๊ฒ ๋‹ค๋Š” ์˜๋ฏธ๋‹ค.
  • ๊ทธ๋Ÿฌ๋‚˜ ํŠน๋ณ„ํ•œ ์ด์œ ๊ฐ€ ์—†๋‹ค๋ฉด ์˜ˆ์™ธ๋ฅผ ๊ฒ€์ถœํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ ์ „๋ฐฉ์˜ ์œ„์น˜์—์„œ ์žก์•„์„œ Logging์„ ํ•˜๋˜ ๋กœ์ง์— ์ด๋ฅผ ๋ฐ˜์˜ํ•˜๋˜ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
  • ์ด Checked Exception์€ ํ†ต์ƒ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ์„ ๊ณ„์† ์šด์˜ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉํ•œ๋‹ค.