Study/Effective Java

์•„์ดํ…œ9. try-finally๋ณด๋‹ค๋Š” try-with-resources๋ฅผ ์‚ฌ์šฉํ•˜๋ผ

sw_develop 2023. 5. 6. 18:56

๐Ÿ“์ƒํ™ฉ

  • ์ž๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” close ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด ์ง์ ‘ ๋‹ซ์•„์ค˜์•ผ ํ•˜๋Š” ์ž์›์ด ์กด์žฌํ•จ
    • ex) InputStream, OutputStream, java.sql.Connection
    • ์ด๋Ÿฌํ•œ ์ž์› ๋‹ซ๊ธฐ๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋†“์น˜๊ธฐ ์‰ฌ์›Œ ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋Š” ์„ฑ๋Šฅ ๋ฌธ์ œ๋กœ ์ด์–ด์ง€๊ธฐ๋„ ํ•จ
  • ๊ทธ๋ ‡๋‹ค๋ฉด ๊ผญ ํšŒ์ˆ˜ํ•ด์•ผ ํ•˜๋Š” ์ž์›์„ ๋‹ค๋ฃฐ ๋•Œ๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?

 

๐Ÿ“๋ฐฉ๋ฒ•

1) try-finally

  • ์ „ํ†ต์ ์œผ๋กœ ์ž์›์ด ์ œ๋Œ€๋กœ ๋‹ซํž˜์„ ๋ณด์žฅํ•˜๋Š” ์ˆ˜๋‹จ

 

์ฝ”๋“œ 9-1 try-finally - ๋” ์ด์ƒ ์ž์›์„ ํšŒ์ˆ˜ํ•˜๋Š” ์ตœ์„ ์˜ ๋ฐฉ์ฑ…์ด ์•„๋‹˜

public class BadBufferedReader extends BufferedReader {
    public BadBufferedReader(Reader in, int sz) {
        super(in, sz);
    }

    public BadBufferedReader(Reader in) {
        super(in);
    }

    @Override
    public String readLine() throws IOException {
        throw new CharConversionException();
    }

    @Override
    public void close() throws IOException {
        throw new StreamCorruptedException();
    }
}
public class TopLine {

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

    public static void main(String[] args) throws IOException {
        System.out.println(firstLineOfFile("pom.xml"));
    }
}

๊ฒฐ์ 

  • ์„œ๋ฒ„์— ๋ฌผ๋ฆฌ์ ์ธ ๋ฌธ์ œ ๋ฐœ์ƒ ์‹œ readLine()๊ณผ close() ๋ฉ”์„œ๋“œ์—์„œ ๋ชจ๋‘ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ
  • ์ด๋•Œ ๋‘ ๋ฒˆ์งธ ์˜ˆ์™ธ๊ฐ€ ์ฒซ ๋ฒˆ์งธ ์˜ˆ์™ธ๋ฅผ ๋ฎ์–ด์”Œ์›Œ์„œ ์Šคํƒ ์ถ”์  ๋‚ด์—ญ์— ์ฒซ ๋ฒˆ์งธ ์˜ˆ์™ธ์— ๊ด€ํ•œ ์ •๋ณด๋Š” ๋‚จ์ง€ ์•Š๊ฒŒ ๋˜์–ด ๋””๋ฒ„๊น…์ด ์–ด๋ ค์›Œ์ง
    • ๋‘ ๋ฒˆ์งธ ์˜ˆ์™ธ ๋Œ€์‹  ์ฒซ ๋ฒˆ์งธ ์˜ˆ์™ธ๋ฅผ ๊ธฐ๋กํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ์ง€์ €๋ถ„ํ•ด์ง

 

์ฝ”๋“œ 9-2 ์ž์›์ด ๋‘˜ ์ด์ƒ์ด๋ฉด try-finally ๋ฐฉ์‹์€ ๋„ˆ๋ฌด ์ง€์ €๋ถ„ํ•จ

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();
    }
}

 

2) try-with-resources (๊ถŒ์žฅ)

  • ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๋ฌธ์ œ๋“ค์€ ์ž๋ฐ” 7์˜ try-with-resources ๋•์— ๋ชจ๋‘ ํ•ด๊ฒฐ๋˜์—ˆ์Œ
    • catch ์ ˆ๋„ ํ•จ๊ป˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•จ

 

  • ์กฐ๊ฑด
    • ํ•ด๋‹น ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ•ด๋‹น ์ž์›์ด AutoCloseable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•จ
      • ์ž๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์˜ ์ˆ˜๋งŽ์€ ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ด๋ฏธ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ํ™•์žฅํ•ด๋‘ 
      • ๋‹ซ์•„์•ผ ํ•˜๋Š” ์ž์›์„ ๋œปํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•œ๋‹ค๋ฉด ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ฐ˜๋“œ์‹œ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Œ

 

์ฝ”๋“œ 9-3 try-with-resources - ์ž์›์„ ํšŒ์ˆ˜ํ•˜๋Š” ์ตœ์„ ์ฑ…!

public class TopLine {

    static String firstLineOfFile(String path) throws IOException {
        try(BufferedReader br = new BadBufferedReader(new FileReader(path))) { //try-with-resources ์ ์šฉ
            return br.readLine();
        }
    }

    public static void main(String[] args) throws IOException {
        System.out.println(firstLineOfFile("pom.xml"));
    }
}

๊ฐœ์„ 

  • readLine()๊ณผ close() ํ˜ธ์ถœ ๋ชจ๋‘์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, close()์—์„œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๋Š” ์ˆจ๊ฒจ์ง€๊ณ  readLine()์—์„œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๊ฐ€ ๊ธฐ๋ก๋จ
    • ์ด๋ ‡๊ฒŒ ์ˆจ๊ฒจ์ง„ ์˜ˆ์™ธ๋“ค์€ ๊ทธ๋ƒฅ ๋ฒ„๋ ค์ง€์ง€ ์•Š๊ณ , ์Šคํƒ ์ถ”์  ๋‚ด์—ญ์— suppressed ๊ผฌ๋ฆฌํ‘œ๋ฅผ ๋‹ฌ๊ณ  ์ถœ๋ ฅ๋จ
    • ์ž๋ฐ” 7์—์„œ Throwable์— ์ถ”๊ฐ€๋œ getSuppressed ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ ์ฝ”๋“œ์—์„œ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Œ

 

์–ด๋–ป๊ฒŒ ์ด๋ ‡๊ฒŒ ๋™์ž‘ํ• ๊นŒ?

  • target ํด๋” ๋‚ด์˜ ํด๋ž˜์Šค ํŒŒ์ผ์„ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Œ (์ธํ…”๋ฆฌ์ œ์ด์—์„œ ์ปดํŒŒ์ผ๋œ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ๋ณด๊ธฐ ์‰ฝ๊ฒŒ ์ œ๊ณตํ•ด์คŒ)
//TopLine.class
public class TopLine {
    public TopLine() {
    }

    static String firstLineOfFile(String path) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(path));

        String var2;
        try {
            var2 = br.readLine();
        } catch (Throwable var5) { //1)
            try {
                br.close();
            } catch (Throwable var4) { //2)
                var5.addSuppressed(var4);
            }

            throw var5;
        }

        br.close();
        return var2;
    }

    public static void main(String[] args) throws IOException {
        String path = args[0];
        System.out.println(firstLineOfFile(path));
    }
}
  • 1) readLine()์—์„œ์˜ ์˜ˆ์™ธ๋ฅผ catch๋ฌธ์œผ๋กœ ์žก์Œ
  • 2) catch๋ฌธ ๋‚ด์—์„œ close() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ํ•ด๋‹น ๋ฉ”์„œ๋“œ์—์„œ์˜ ์˜ˆ์™ธ๋ฅผ catch๋ฌธ์œผ๋กœ ์žก์Œ
    • ์ด๋•Œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๋Š” Throwable์˜ addSuppressed()๋ฅผ ํ†ตํ•ด ์ถ”๊ฐ€๋จ

 

์ฝ”๋“œ 9-4 ๋ณต์ˆ˜์˜ ์ž์›์„ ์ฒ˜๋ฆฌํ•˜๋Š” try-with-resources

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);
         }
    }
}

 

๐Ÿ“ํ•ต์‹ฌ ์ •๋ฆฌ

  • ๊ผญ ํšŒ์ˆ˜ํ•ด์•ผ ํ•˜๋Š” ์ž์›์„ ๋‹ค๋ฃฐ ๋•Œ๋Š” try-finally ๋ง๊ณ , try-with-resources๋ฅผ ์‚ฌ์šฉํ•˜์ž
    • ์ฝ”๋“œ๋Š” ๋” ์งง๊ณ  ๋ถ„๋ช…ํ•ด์ง€๊ณ , ๋งŒ๋“ค์–ด์ง€๋Š” ์˜ˆ์™ธ ์ •๋ณด๋„ ํ›จ์”ฌ ์œ ์šฉํ•จ