[์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”] Item08 ์™„๋ฒฝ๊ณต๋žต. AutoClosable

2023. 1. 25. 13:19ใ†JAVA/Effective JAVA

728x90

 

item08. finalizer์™€ cleaner ์‚ฌ์šฉ์„ ํ”ผํ•˜๋ผ.  

" p43. AutoClosable "

 

 

AutoClosable์ด๋ž€? 

: try-with-resources๋ฅผ ์ง€์›ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. 

/*
 * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.lang;

/**
 * An object that may hold resources (such as file or socket handles)
 * until it is closed. The {@link #close()} method of an {@code AutoCloseable}
 * object is called automatically when exiting a {@code
 * try}-with-resources block for which the object has been declared in
 * the resource specification header. This construction ensures prompt
 * release, avoiding resource exhaustion exceptions and errors that
 * may otherwise occur.
 *
 * @apiNote
 * <p>It is possible, and in fact common, for a base class to
 * implement AutoCloseable even though not all of its subclasses or
 * instances will hold releasable resources.  For code that must operate
 * in complete generality, or when it is known that the {@code AutoCloseable}
 * instance requires resource release, it is recommended to use {@code
 * try}-with-resources constructions. However, when using facilities such as
 * {@link java.util.stream.Stream} that support both I/O-based and
 * non-I/O-based forms, {@code try}-with-resources blocks are in
 * general unnecessary when using non-I/O-based forms.
 *
 * @author Josh Bloch
 * @since 1.7
 */
public interface AutoCloseable {
    /**
     * Closes this resource, relinquishing any underlying resources.
     * This method is invoked automatically on objects managed by the
     * {@code try}-with-resources statement.
     *
     * <p>While this interface method is declared to throw {@code
     * Exception}, implementers are <em>strongly</em> encouraged to
     * declare concrete implementations of the {@code close} method to
     * throw more specific exceptions, or to throw no exception at all
     * if the close operation cannot fail.
     *
     * <p> Cases where the close operation may fail require careful
     * attention by implementers. It is strongly advised to relinquish
     * the underlying resources and to internally <em>mark</em> the
     * resource as closed, prior to throwing the exception. The {@code
     * close} method is unlikely to be invoked more than once and so
     * this ensures that the resources are released in a timely manner.
     * Furthermore it reduces problems that could arise when the resource
     * wraps, or is wrapped, by another resource.
     *
     * <p><em>Implementers of this interface are also strongly advised
     * to not have the {@code close} method throw {@link
     * InterruptedException}.</em>
     *
     * This exception interacts with a thread's interrupted status,
     * and runtime misbehavior is likely to occur if an {@code
     * InterruptedException} is {@linkplain Throwable#addSuppressed
     * suppressed}.
     *
     * More generally, if it would cause problems for an
     * exception to be suppressed, the {@code AutoCloseable.close}
     * method should not throw it.
     *
     * <p>Note that unlike the {@link java.io.Closeable#close close}
     * method of {@link java.io.Closeable}, this {@code close} method
     * is <em>not</em> required to be idempotent.  In other words,
     * calling this {@code close} method more than once may have some
     * visible side effect, unlike {@code Closeable.close} which is
     * required to have no effect if called more than once.
     *
     * However, implementers of this interface are strongly encouraged
     * to make their {@code close} methods idempotent.
     *
     * @throws Exception if this resource cannot be closed
     */
    void close() throws Exception;
}

AutoClosable ์€ close ๋ฉ”์„œ๋“œ ํ•˜๋‚˜๋งŒ์„ ๊ฐ€์ง„ ์ธํ„ฐํŽ˜์ด์Šค์ด์ง€๋งŒ ๊ทธ๋ ‡๋‹ค๊ณ  ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์•„๋‹ˆ๋‹ค. (๊ทธ๋Ÿด ๋ชฉ์ ์œผ๋กœ ๋งŒ๋“  ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์•„๋‹˜)

๊ทธ๋ฆฌ๊ณ  close ๋ฉ”์„œ๋“œ๋Š” Exception ์—๋Ÿฌ๋ฅผ ๋˜์ง€๊ณ  ์žˆ๋‹ค. 

 

try-with-resources๋ฅผ ์ง€์›ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ผ๋Š” ๊ฒƒ์€ ์ฆ‰ ์ž์›ํ•ด์ œ๋ฅผ ํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋กœ 

์ž์› ํ•ด์ œ๋˜๊ธธ ๋ฐ”๋ผ๋Š” ํด๋ž˜์Šค๋ผ๋ฉด AutoCloseable์„ implementํ•ด์„œ ๊ตฌํ˜„ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. 

 

public class AutoClosableIsGood implements AutoCloseable{
    private BufferedInputStream inputStream;

    @Override
    public void close(){
        // idempotent ํ•ด์•ผ ํ•œ๋‹ค.(๋ช‡๋ฒˆ์„ ํ˜ธ์ถœํ•˜๋”๋ผ๋„ ๋™์ผํ•œ ๊ฒฐ๊ณผ๊ฐ€ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค.) AutoClosable ์€ ๊ถŒ์žฅ, Closeable ํ•„์ˆ˜
        try {
            inputStream.close();
        } catch (IOException e) {
            throw new RuntimeException("failed to close " + inputStream);
        }
    }
}

๊ทธ๋ฆฌ๊ณ  ์—ฌ๊ธฐ์„œ BufferedInputStream์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— IOException์ด ๋ฐœ์ƒํ•  ํ™•๋ฅ ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Exception ๋ณด๋‹ค ๊ตฌ์ฒด์ ์ธ IOException์„ ์žก์•„์คฌ๋‹ค.  ์ด๋ ‡๊ฒŒ ์—ฌ๊ธฐ์„œ ์˜ˆ์™ธ๋ฅผ ์žก๊ณ  ๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ๋กœ ๋ณ€ํ™˜ํ•ด์„œ ๋˜์ ธ์ฃผ๋ฉด ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—์„œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ์•ˆํ•ด์ค˜๋„ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฐฉ๋ฒ•์„ ๊ถŒ์žฅํ•œ๋‹ค. 

 

 

public class App {
    public static void main(String[] args) {
        try (AutoClosableIsGood good = new AutoClosableIsGood()){
            // TODO ์ž์› ๋ฐ˜๋‚ฉ ์ฒ˜๋ฆฌ๊ฐ€ ๋จ
        }
    }
}

๊ทธ๋ฆฌ๊ณ  ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—์„œ๋Š” ์ด๋Ÿฐ์‹์œผ๋กœ ์‚ฌ์šฉํ•ด์ฃผ๋ฉด ๋œ๋‹ค. 

 

 

Closable 

: AutoClosable์„ ๊ตฌํ˜„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค

AutoClosable๋ณด๋‹ค ์ข€ ๋” ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค๋กœ AutoCloseable์€ Exception์„ ๋˜์ง€๋Š” ๋ฐ˜๋ฉด, Closeable์€ IOException์„ ๋˜์ง„๋‹ค. 

๊ทธ๋ฆฌ๊ณ  AutoCloseable์€ idempotent๋ฅผ ๊ถŒ์žฅํ•˜์ง€๋งŒ, Closeable์€ ๋ฐ˜๋“œ์‹œ idempotent ํ•ด์•ผ ํ•œ๋‹ค. 

 

โ“idempotent๋ž€? 

๋ฒˆ์—ญํ•˜๋ฉด '๋ฉฑ๋“ฑ์„ฑ' ์ด๋ผ๊ณ  ์ข€ ๋” ์–ด๋ ค์šด๋ง๋กœ ๋ฒˆ์—ญ๋˜๋Š”๋ฐ .. 

์—ฐ์‚ฐ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ์ ์šฉํ•˜๋”๋ผ๋„ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์ง€์ง€ ์•Š๋Š” ์„ฑ์งˆ์—ฐ์‚ฐ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐ˜๋ณตํ•˜์—ฌ๋„ ํ•œ ๋ฒˆ๋งŒ ์ˆ˜ํ–‰๋œ ๊ฒƒ๊ณผ ๊ฐ™์€ ์„ฑ์งˆ์„ ์˜๋ฏธํ•œ๋‹ค. 

 

 

 

 

 

 

 

 

 

 

 

 

728x90