Effective Java - Item 7
์๋ฐ์ฒ๋ผ ๊ฐ๋น์ง ์ปฌ๋ ํฐ๋ฅผ ๊ฐ์ถ ์ธ์ด๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ์ ์ ๊ฒฝ ์ฐ์ง ์์๋ ๋๋ค๊ณ ์๊ฐํ ์ ์์ง๋ง, ์ ๋ ๋ฌด์ํด์๋ ์๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.util.Arrays;
import java.util.EmptyStackException;
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
}
public void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
โ ์คํ์ ๊ตฌํํ ๊ฐ๋จํ ์ฝ๋
์ ์ฝ๋๋ ์คํ์ ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ฝ๋์ด๋ค.
์ธ๋ป ๋ณด๋ฉด ์๋ฌด๋ฐ ๋ฌธ์ ๊ฐ ์๋ ์ฝ๋๋ผ๊ณ ์๊ฐํ๊ธฐ ์ฝ์ง๋ง, ํด๋น ์ฝ๋์์๋ ์คํ์์ ๊บผ๋ด์ง ๊ฐ์ฒด๋ค์ ๊ฐ๋น์ง ์ปฌ๋ ํฐ๊ฐ ํ์ํ์ง ์๋๋ค.
์คํ์ด ๋ฐฐ์ด์์ ์ฌ์ ํ ๊ทธ ๊ฐ์ฒด๋ค์ ์ฐธ์กฐํ๊ณ ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๋ ๊ฒ ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ํ๋ ์ด๋ ค๋๋ฉด ํด๋น ๊ฐ์ฒด ๋ฟ ์๋๋ผ ๊ทธ ๊ฐ์ฒด๊ฐ ์ฐธ์กฐํ๊ณ ์๋ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ํ์ ํ์ง ๋ชปํ๋ค.
๋๋ฌธ์ ๊ณ์ํด์ ์คํ๋๋ค๋ฉด ๊ฐ๋น์ง ์ปฌ๋ ์ ์ ํ๋๊ณผ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ๋์ด๋ ์ฑ๋ฅ์ด ์ ํ๋๋ค.
๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ์ฌํ ๊ฒฝ์ฐ์๋ ๋์คํฌ ํ์ด์ง์ด๋ OutOfMemoryError๊ฐ ๋ฐ์ํ์ฌ ์๊ธฐ์น ์๊ฒ ํ๋ก๊ทธ๋จ์ด ๋ ์๋ ์๋ค.
์ด๋ฌํ ๋ฌธ์ ์ ํด๋ฒ์ ๋ฐ๋ก ๋ค ์ด ๊ฐ์ฒด๋ null ์ฒ๋ฆฌํ์ฌ ์ฐธ์กฐ๋ฅผ ํด์ ํ๋ ๊ฒ์ด๋ค.
1
2
3
4
5
6
7
public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
element[size] = null; // ๋ค ์ด ๊ฐ์ฒด ์ฐธ์กฐ ํด์
return result;
}
์คํ์ ์์ฒด์ ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ด๋ฆฌํ๊ณ , ๋ฐฐ์ด์ ํ์ฑํ ์์ญ์ ์ํ ๊ฐ์ฒด ๋ง์ ์ฌ์ฉํ๊ณ ๋นํ์ฑํ ์์ญ์ ์ฌ์ฉํ์ง ์๋๋ฐ ๊ฐ๋น์ง ์ปฌ๋ ํฐ๋ ์ด ์ฌ์ค์ ์ ์๊ฐ ์๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ null ์ฒ๋ฆฌ๋ฅผ ํตํด ๊ฐ๋น์ง ์ปฌ๋ ํฐ์๊ฒ ์ด ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ง ์๋๋ค๋ ๊ฒ์ ์๋ ค์ผ ํ๋ค.
์ผ๋ฐ์ ์ผ๋ก ์คํ์ฒ๋ผ ์๊ธฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ง์ ๊ด๋ฆฌํ๋ ํด๋์ค๋ผ๋ฉด ๊ฐ์ฒด๋ฅผ ๋ค ์ฌ์ฉํ ์ฆ์ null ์ฒ๋ฆฌํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์์ ์ฃผ์ํด์ผ ํ๋ค.
๋ค๋ง ํญ์ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ์ผ์ผ์ด null ์ฒ๋ฆฌ๋ฅผ ํ๋ ๊ฒ์ ํ๋ก๊ทธ๋จ์ ์ง์ ๋ถํ๊ฒ ๋ง๋ค ๋ฟ์ด๋ฏ๋ก ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ null ์ฒ๋ฆฌํ๋ ์ผ์ ์์ธ์ ์ธ ๊ฒฝ์ฐ์ฌ์ผ ํ๋ค.
๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ํด์ ํ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ๊ทธ ์ฐธ์กฐ๋ฅผ ๋ด์ ๋ณ์๋ฅผ ์ ํจ ๋ฒ์(Scope) ๋ฐ์ผ๋ก ๋ฐ์ด๋ด๋ ๊ฒ์ด๋ค.
์บ์ ์ญ์ ์๊ธฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ง์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ์ผ์ผํจ๋ค.
๋ง์ฝ key๋ฅผ ์ฐธ์กฐํ๋ ๋์์๋ง entry๊ฐ ์ด์์์ผ๋ฉด ๋๋ ์บ์๋ผ๋ฉด WeakHashMap
์ ์ฌ์ฉํ์ฌ ์บ์๋ฅผ ์์ฑํ์. ๋ค ์ด entry๋ ๊ทธ ์ฆ์ ์๋์ผ๋ก ์ ๊ฑฐ๋๋ค.
ํ์ง๋ง ๋๋ถ๋ถ ์บ์ ์ํธ๋ฆฌ์ ์ ํจ ๊ธฐ๊ฐ์ ์ ํํ ์ ์ํ๊ธฐ๊ฐ ์ด๋ ต๋ค. ๊ทธ๋์ ์บ์์ ๋ฃ์ ์๊ฐ์ด ๊ธธ์๋ก ์ํธ๋ฆฌ์ ๊ฐ์น๋ฅผ ๋จ์ด๋จ๋ฆฌ๋ ๋ฐฉ์์ ์ฃผ๋ก ์ฌ์ฉํ๋ค.
์ด๋ฐ ๋ฐฉ์์์๋ ScheduledThreadPoolExcutor ๊ฐ์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ๋ถ์ ์์ ์ผ๋ก ์ํธ๋ฆฌ๋ฅผ ์ฒญ์ํด์ฃผ์ด์ผ ํ๋ค.
๋ง์ง๋ง์ผ๋ก listener์ callback ์ญ์ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ์ผ์ด๋๋ ์ฃผ๋ฒ์ด๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ์ฝ๋ฐฑ์ ๋ฑ๋ก๋ง ํ๊ณ ๋ช ํํ๊ฒ ํด์งํ์ง ์๋๋ค๋ฉด, ๋ฌด์ธ๊ฐ ์กฐ์นํด์ฃผ์ง ์๋ ์ด์ ๊ณ์ํด์ ์์ฌ๊ฐ๋ค. ์ด๋ด ๋ ์ฝ๋ฐฑ์ ์ฝํ ์ฐธ์กฐ(weak reference)๋ก ์ ์ฅํ๋ฉด ๊ฐ๋น์ง ์ปฌ๋ ํฐ๊ฐ ์ง์ ์๊ฑฐํด๊ฐ ์ ์๋ค.
๋ฉ๋ชจ๋ฆฌ ๋์๋ ๊ฒ์ผ๋ก ์ ๋๋ฌ๋์ง ์๊ธฐ ๋๋ฌธ์ ๋ฐ๊ฒฌํ๊ธฐ๊ฐ ์ด๋ ต๋ค. ์ฒ ์ ํ ์ฝ๋ ๋ฆฌ๋ทฐ๋ ํ ํ๋กํ์ผ๋ฌ ๊ฐ์ ๋๋ฒ๊น ๋๊ตฌ๋ฅผ ๋์ํด์ผ๋ง ๋ฐ๊ฒฌํ๋ ๊ฒฝ์ฐ๋ ์๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์๋ฐฉ๋ฒ์ ์ฒ ์ ํ ์ตํ๋๋ ๊ฒ์ด ๊ฐ์ฅ ์ค์ํ๋ค.