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

2023. 1. 25. 11:24ใ†JAVA/Effective JAVA

728x90

 

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

" p42. Finalizer ๊ณต๊ฒฉ"

 

 

https://hyejin.tistory.com/1011

 

[์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”] Item8. finalizer์™€ cleaner ์‚ฌ์šฉ์„ ํ”ผํ•˜๋ผ.

item07. ๋‹ค ์“ด ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ํ•ด์ œํ•˜๋ผ. ์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ” part 1์—์„œ๋Š” ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ์†Œ๋ฉธ์— ๋Œ€ํ•ด์„œ ์–˜๊ธฐํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์ง€๊ธˆ์€ ์ €๋ฒˆ item ๋ถ€ํ„ฐ๋Š” ๊ฐ์ฒด ์†Œ๋ฉธ์— ๋Œ€ํ•ด์„œ ์ด์•ผ๊ธฐ ํ•˜๊ณ  ์žˆ๋‹ค. ์šฐ์„  ์ž๋ฐ”์—์„œ๋Š” ๋‘

hyejin.tistory.com

์—ฌ๊ธฐ์„œ finalizer๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋˜๋Š” ์ด์œ  ์ค‘ ํ•˜๋‚˜๋กœ "finalizer๋ฅผ ์‚ฌ์šฉํ•œ ํด๋ž˜์Šค๋Š” finalizer ๊ณต๊ฒฉ์— ๋…ธ์ถœ๋˜์–ด ์‹ฌ๊ฐํ•œ ๋ณด์•ˆ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋‹ค" ๋ผ๊ณ  ํ–ˆ๋Š”๋ฐ ์ด๋•Œ finalizer ๊ณต๊ฒฉ์€ ์ƒ์„ฑ์ž๋‚˜ ์ง๋ ฌํ™” ๊ณผ์ •์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ์ด ์ƒ์„ฑ๋˜๋‹ค ๋งŒ ๊ฐ์ฒด์—์„œ ์•…์˜์ ์ธ ํ•˜์œ„ ํด๋ž˜์Šค์˜ finalizer๊ฐ€ ์ˆ˜ํ–‰๋  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค๊ณ  ํ•œ๋‹ค. 

 

public class Account {
    private String accountId;

    public Account(String accountId) {
        this.accountId = accountId;

        if (accountId.equals("aaa")) {
            throw new IllegalArgumentException("aaa์˜ ๊ณ„์ •์„ ๋ง‰์Šต๋‹ˆ๋‹ค.");
        }
    }

    public void transfer(BigDecimal amount, String to) {
        System.out.printf("transfer %f from %s to %s", amount, accountId, to);
    }
 }

์ด๋ ‡๊ฒŒ aaa์˜ ๊ณ„์ •์„ ๋ง‰๋Š” Account ํด๋ž˜์Šค๊ฐ€ ์žˆ๊ณ , aaa๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ์—๊ฒŒ ๊ณ„์ขŒ ์ด์ฒด๋ฅผ ๋ชปํ•˜๊ฒŒ ํ•œ๋‹ค. 

 

 

class AccountTest {

    @Test
    void ์ผ๋ฐ˜_๊ณ„์ •() {
        Account account = new Account("hyejin");
        account.transfer(BigDecimal.valueOf(10.4), "hello");
    }

    @Test
    void aaa_๊ณ„์ •() {
        Account account = new Account("aaa");
        account.transfer(BigDecimal.valueOf(10.4), "hello~");
    }
  }

๋”ฐ๋ผ์„œ ์ผ๋ฐ˜ ๊ณ„์ •์€ ํ…Œ์ŠคํŠธ ์„ฑ๊ณตํ•˜๋Š” ๋ฐ˜๋ฉด, aaa ๊ณ„์ •์€ ์‹คํŒจํ•œ๋‹ค. 

 

 

์ด๋ ‡๊ฒŒ ๋ณด๋ฉด aaa๋Š” ๊ณ„์ •์ด ๋ง‰ํ˜€ ๊ณ„์ขŒ ์ด์ฒด๋ฅผ ํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ ๊ฐ™์•„ ๋ณด์ด์ง€๋งŒ 

finalizer ๊ณต๊ฒฉ์„ ์‚ฌ์šฉํ•˜๋ฉด aaa๊ฐ€ ๊ณ„์ขŒ ์ด์ฒดํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

public class BrokenAccount extends Account {

    public BrokenAccount(String accountId) {
        super(accountId);
    }

    @Override
    protected void finalize() throws Throwable {
        this.transfer(BigDecimal.valueOf(100), "hyejin");
    }
}

Account๋ฅผ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ . finalize๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•ด์„œ ์—ฌ๊ธฐ์„œ transfer ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. 

 

@Test
void broken_aaa_๊ณ„์ •() throws InterruptedException {
    Account account = null;
    try {
        account = new BrokenAccount("aaa");
    } catch (Exception e) {
        System.out.println("์ด๋Ÿฌ๋ฉด???");
    }
    System.gc();
    Thread.sleep(3000L); // gcํ•˜๊ธฐ ์œ„ํ•œ ์‹œ๊ฐ„
}

๊ทธ๋ฆฌ๊ณ  ์šฐ์„  null๋กœ ๋งŒ๋“ค๊ณ , aaa ๊ณ„์ •์€ IllegalArgumentException์„ ๋ฐœ์ƒ์‹œํ‚ค๋ฏ€๋กœ try-catch๋กœ ์žก์•„์ฃผ๊ณ , gc๋ฅผ ์‹œ์ž‘์‹œํ‚ค๋ฉด 

finalizer๊ฐ€ ๋™์ž‘ํ•˜๋ฉด์„œ transer ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค..! 

 

์ด๋Ÿฐ finalizer ๊ณต๊ฒฉ์„ ๋ง‰๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ทธ๋ƒฅ Account ํด๋ž˜์Šค ์ž์ฒด๋ฅผ final๋กœ ํ•˜์—ฌ ์ƒ์†๋ฐ›์ง€ ๋ชปํ•˜๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ, 

๊ทผ๋ฐ ์ด ํด๋ž˜์Šค๊ฐ€ ์ƒ์† ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ ธ์•ผํ•œ๋‹ค๋ฉด 

public class Account {
    private String accountId;

    public Account(String accountId) {
        this.accountId = accountId;

        if (accountId.equals("aaa")) {
            throw new IllegalArgumentException("aaa์˜ ๊ณ„์ •์„ ๋ง‰์Šต๋‹ˆ๋‹ค.");
        }
    }

    public void transfer(BigDecimal amount, String to) {
        System.out.printf("transfer %f from %s to %s", amount, accountId, to);
    }

    @Override
    protected  final void finalize() throws Throwable {
        // ์˜ค๋ฒ„๋ผ์ด๋”ฉ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋„๋ก ๋ง‰์•„๋‘ 
    }
}

์ด๋ ‡๊ฒŒ Account ํด๋ž˜์Šค์—์„œ finalize๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ๋ชปํ•˜๊ฒŒ final๋กœ ์„ ์–ธํ•ด์„œ ๋ง‰์•„๋‘๋ฉด ๋œ๋‹ค. 

๊ทธ๋ฆฌ๊ณ  ๋‹ค์‹œ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๋ฉด ์ด์ œ aaa๊ฐ€ ๊ณ„์ขŒ ์ด์ฒด๋ฅผ ํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

 

 

 

 

 

 

 

 

 

728x90