item 9 junghyunlyoo - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

์ž์› ๋‹ซ๊ธฐ์˜ ์ค‘์š”์„ฑ

InputStream, OutputStream, java.sql.Connection ๋“ฑ์€ close ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ง์ ‘ ๋‹ซ์•„์ค˜์•ผ ํ•œ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ๊นœ๋นกํ•˜๊ณ  ์ž์›์„ ๋‹ซ์ง€ ์•Š์œผ๋ฉด ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋Š” ์„ฑ๋Šฅ ๋ฌธ์ œ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

์ด ์ƒํ™ฉ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด finalizer๋ฅผ ํ™œ์šฉํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์•„๋‹ˆ๋‹ค. (item 8)

์ผ๋ฐ˜์ ์œผ๋กœ ์ž์›์„ ๋‹ซ๋Š” ๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ•์ธ try-fianlly์™€ java 7 ์ดํ›„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” try-with-resources์ด๋‹ค.

์ž์›์„ ๋‹ซ๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ• :: try-finally

static String firstLineOfFile(String path) throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        br.close();
    }
}

๋งŒ์•ฝ ์ž์›์ด ํ•˜๋‚˜ ๋” ๋Š˜์–ด๋‚œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

static void copy(String src, String dst) throws IOException {
    InputStream in = new FileInputStream(src);
    try {
        OutputStream out = new FileOutputStream(dst);
        try {
            byte[] buf = new byte[BUFFER_SIZE];
            int n;
            while ((n = in.read(buf)) >= 0)
                out.write(buf, 0, n);
        } finally {
            out.close();
        }
    } finally {
        in.close();
    }
}

๋„ˆ๋ฌด ๋ณด๊ธฐ๊ฐ€ ํž˜๋“ค๋‹ค.


try-finally์˜ 2๊ฐ€์ง€ ๋‹จ์ ์ด ์žˆ๋‹ค.

์ฒซ ๋ฒˆ์งธ ๋‹จ์ ์€ ๊ฐ€๋…์„ฑ์ด ์•ˆ์ข‹๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๋‘ ๋ฒˆ์งธ ๋‹จ์ ์€ ์Šคํƒ ์ถ”์ ์ด ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

์œ„์˜ firstLineOfFile ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ์ข€ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณด์ž.

์˜ˆ์™ธ๋Š” try ๋ธ”๋ก๊ณผ finally ๋ธ”๋ก ๋ชจ๋‘์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๊ธฐ๊ธฐ์— ๋ฌผ๋ฆฌ์ ์ธ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค๋ฉด firstLineOfFile ๋ฉ”์„œ๋“œ ๋‚ด์˜

readLine ๋ฉ”์„œ๋“œ๊ฐ€ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๊ณ , ๊ฐ™์€ ์ด์œ ๋กœ close ๋ฉ”์„œ๋“œ๋„ ์‹คํŒจํ•œ๋‹ค.

์˜ˆ์™ธ๊ฐ€ ๋‘๊ฐœ๊ฐ€ ์ƒ๊ฒจ๋ฒ„๋ฆฌ๊ณ  close ์˜ˆ์™ธ๊ฐ€ readLine ์˜ˆ์™ธ๋ฅผ ๋ฎ์–ด๋ฒ„๋ฆฐ๋‹ค.

์‹ค์ œ๋กœ ์Šคํƒ ์ถ”์  ๋‚ด์—ญ์— ์ฒซ ๋ฒˆ์งธ ์˜ˆ์™ธ์— ๊ด€ํ•œ ๋‚ด์šฉ์€ ๋“ฑ์žฅํ•˜์ง€ ์•Š๊ฒŒ ๋˜๊ณ ,

์ด๋Š” ์‹ค์ œ ์‹œ์Šคํ…œ์—์„œ์˜ ๋””๋ฒ„๊น…์„ ๋ชน์‹œ ์–ด๋ ต๊ฒŒ ํ•œ๋‹ค.

์™œ๋ƒํ•˜๋ฉด ์ฒซ ๋ฒˆ์งธ ์˜ˆ์™ธ๋ถ€ํ„ฐ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ๋ณดํ†ต ์—๋Ÿฌ ํ•ด๊ฒฐ์˜ ์ˆœ์„œ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋‘ ๋ฒˆ์งธ ์˜ˆ์™ธ ๋Œ€์‹  ์ฒซ ๋ฒˆ์งธ ์˜ˆ์™ธ๋ฅผ ๊ธฐ๋กํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ์ง€์ €๋ถ„ํ•ด์ง„๋‹ค.

java 7์— ๋“ฑ์žฅํ•œ try-with-resources

try-finally์—์„œ์˜ ๋ฌธ์ œ๋“ค์„ try-with-resources๊ฐ€ ๊น”๋”ํ•˜๊ฒŒ ํ•ด๊ฒฐํ•œ๋‹ค.

try-with-resources๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ•ด๋‹น ์ž์›์ด AutoCloseable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

์™œ๋ƒํ•˜๋ฉด close ๋ฉ”์†Œ๋“œ๋ฅผ ๋ฌด์กฐ๊ฑด ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•ด AutoCloseable๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

AutoCloseable ์ธํ„ฐํŽ˜์ด์Šค๋Š” close ๋ฉ”์„œ๋“œ ํ•˜๋‚˜๋งŒ ์ •์˜๋˜์–ด ์žˆ๋‹ค.

์ž๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์˜ ์ˆ˜๋งŽ์€ ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ด๋ฏธ AutoCloseable์„ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ํ™•์žฅํ•ด๋’€๋‹ค.

๋‹ซ์•„์•ผ ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•œ๋‹ค๋ฉด AutoCloseable์„ ๋ฐ˜๋“œ์‹œ ๊ตฌํ˜„ํ•˜์—ฌ try-with-resources๋ฅผ ์‚ฌ์šฉํ•˜์ž.

static String firstLineOfFile(String path) throws IOException {
    try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}

์šฐ์„  ๊ต‰์žฅํžˆ ๊น”๋”ํ•˜๋‹ค

static void copy(String src, String dst) throws IOException {
    try (InputStream in = new FileInputStream(src);
         OutputStream out = new FileOutputStream(dst)) {
        byte[] buf = new byte[BUFFER_SIZE];
        int n;
        while ((n = in.read(buf)) >= 0)
            out.write(buf, 0, n);
    }
}

2๊ฐœ ์ด์ƒ์˜ ์ž์›์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ๊ต‰์žฅํžˆ ๊น”๋”ํ•˜๋‹ค.


๋˜ํ•œ try-finally๋ณด๋‹ค ๋ฌธ์ œ๋ฅผ ์ง„๋‹จํ•˜๊ธฐ๋„ ํ›จ์”ฌ ํŽธํ•˜๋‹ค.

firstLineOfFile ๋ฉ”์†Œ๋“œ๋ฅผ ๋ณด์ž.

readLine๊ณผ ์ฝ”๋“œ์—๋Š” ๋ณด์ด์ง€ ์•Š๋Š” close ๋ชจ๋‘์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด

์Šคํƒ ์ถ”์  ๋‚ด์—ญ์— readLine์—์„œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๊ฐ€ ๋จผ์ € ํ‘œ์‹œ๋œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  close์—์„œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๋Š” ์ˆจ๊ฒจ์กŒ๋‹ค๋Š” ๊ผฌ๋ฆฌํ‘œ์ธ suppressed๋ฅผ ๋‹ฌ๊ณ  ๊ทธ ์ดํ›„์— ๊ฐ™์ด ์ถœ๋ ฅ๋œ๋‹ค.

try-finally์™€ ๋‹ฌ๋ฆฌ ์ฒซ ๋ฒˆ์งธ ์˜ˆ์™ธ๋ถ€ํ„ฐ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

๋˜ํ•œ ์•„๋ž˜์ฒ˜๋Ÿผ java 7์—์„œ Throwble์— ์ถ”๊ฐ€๋œ getSuppressed ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ ์ฝ”๋“œ์—์„œ ๊ฐ€์ ธ์˜ฌ ์ˆ˜๋„ ์žˆ๋‹ค.

try {
    testException1();
} catch (Throwable e) {
    Throwable[] suppExe = e.getSuppressed();

    for (int i = 0; i < suppExe.length; i++) {
        System.out.println("Suppressed Exceptions:");
        System.out.println(suppExe[i]);
    }
}

try-with-resources์—์„œ catch ์‚ฌ์šฉํ•˜๊ธฐ

try-finally์ฒ˜๋Ÿผ try-with-resources์—์„œ๋„ catch ์ ˆ์„ ์“ธ ์ˆ˜ ์žˆ๋‹ค.

catch ์ ˆ ๋•๋ถ„์— try ๋ฌธ์„ ๋” ์ค‘์ฒฉํ•˜์ง€ ์•Š๊ณ ๋„ ๋‹ค์ˆ˜์˜ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

static String firstLineOfFile (String path, String defaultVal){
    try (BufferedReader br = new BufferedReader(
            new FileReader(path))) {
        return br.readLine();
    } catch (IOException e) {
        return defaultVal;
    }
}