๐ ๋ชฉ์ฐจ.
2. ๊ฐ์ฒด ์์ฑ๊ณผ ํ๊ดด
.์์ดํ 1 - ์์ฑ์ ๋์ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ฅผ ๊ณ ๋ คํ๋ผ.
.์์ดํ 2 - ์์ฑ์์ ๋งค๊ฐ๋ณ์๊ฐ ๋ง๋ค๋ฉด ๋น๋๋ฅผ ๊ณ ๋ คํ๋ผ.
.์์ดํ 3 - private ์์ฑ์๋ ์ด๊ฑฐ ํ์ ์ผ๋ก ์ฑ๊ธํด์์ ๋ณด์ฆํ๋ผ.
.์์ดํ 4 - ์ธ์คํด์คํ๋ฅผ ๋ง์ผ๋ ค๊ฑฐ๋ private ์์ฑ์๋ฅผ ์ฌ์ฉํ๋ผ
.์์ดํ 5 - ์์์ ์ง์ ๋ช ์ํ์ง ๋ง๊ณ ์์กด ๊ฐ์ฒด ์ฃผ์ ์ ์ฌ์ฉํ๋ผ
.์์ดํ 6 - ๋ถํ์ํ ๊ฐ์ฒด ์์ฑ์ ํผํ๋ผ
.์์ดํ 7 - ๋ค ์ด ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ํด์ ํ๋ผ.
.์์ดํ 8 - finalizer์ cleaner ์ฌ์ฉ์ ํผํ๋ผ
.์์ดํ 9 - try-finally ๋ณด๋ค๋ try-with-resources๋ฅผ ์ฌ์ฉํ๋ผ.
โ๏ธ ๋ด์ฉ.
2. ๊ฐ์ฒด ์์ฑ๊ณผ ํ๊ดด
ํ์ต ๋ด์ฉ
1. ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ผ ํ ๋์ ๋ง๋ค์ง ๋ง์์ผ ํ ๋ ๊ตฌ๋ถ๋ฒ
2. ์ฌ๋ฐ๋ฅธ ๊ฐ์ฒด ์์ฑ๋ฐฉ๋ฒ
3. ๋ถํ์ํ ์์ฑ์ ํผํ๋ ๋ฐฉ๋ฒ
4. ์ ๋ ํ๊ดด๋จ์ ๋ณด์ฅํ๊ณ ํ๊ดด ์ ์ ์ํํด์ผ ํ ์ ๋ฆฌ ์์ ์ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ
.์์ดํ 1 - ์์ฑ์ ๋์ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ฅผ ๊ณ ๋ คํ๋ผ.
ํด๋์ค๋ ํด๋ผ์ด์ธํธ์ Public ์์ฑ์ ๋์ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ฅผ ์ ๊ณตํ ์ ์๋ค.
๊ฐ ์ฅ์ ๊ณผ ๋จ์
์ฅ์ | ๋จ์ |
์ด๋ฆ์ ๊ฐ์ง ์ ์๋ค. 1. ์๋ฏธ ํํ์ด ๋ ์ ๋๋ค. ex) BigInteger(int) -> BigInteger.probablePrime(int) 2. ํ๋์ ์๊ทธ๋์ฒ๋ก๋ ์์ฑ์๋ฅผ ํ๋๋ง ๋ง๋ค ์ ์๋ ๋ฐ๋ฉด ์ ์ ํฉํ ๋ฆฌ ๋ฉ์๋์๋ ์ ์ฝ์ด ์๋ค. ex) BigInteger(int) -> BigInteger.probablePrime(int), BigInteger.probablePrime2(int), BigInteger.probablePrime3(int) ๋ฑ๋ฑ |
์์์ ํ๋ ค๋ฉด public ์ด๋ protected ์์ฑ์๊ฐ ํ์ํ๋ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ง ์ ๊ณตํ๋ฉด ํ์ ํด๋์ค๋ฅผ ๋ง๋ค ์ ์๋ค. ํฉํฐ๋ฆฌ ๋ฉ์๋๋ ์์ ๋ฐ์ ์ ์๋ค. ๋ค๋ฅด๊ฒ ๋ณด๋ฉด ์์๋ณด๋ค ์ปดํฌ์ง์ ์ ์ฌ์ฉ(์์ดํ 18)ํ๋๋ก ์ ๋ํ๊ณ ๋ถ๋ณ ํ์ (์์ดํ 17)์ผ๋ก ๋ง๋ค๋ ค๋ฉด ์ด ์ ์ฝ์ ์ง์ผ์ผ ํ๋ค๋ ์ ์์ ์คํ๋ ค ์ฅ์ ์ด ๋ ์๋ ์๋ค. |
ํธ์ถ๋ ๋๋ง๋ค ์ธ์คํด์ค๋ฅผ ์๋ก ์์ฑํ์ง๋ ์์๋ ๋๋ค. 1. ์ด๋ก์ธํด ๋ถ๋ณ ํด๋์ค(Immutable class; ์์ดํ 17)์ ์ธ์คํด์ค๋ฅผ ๋ฏธ๋ฆฌ ๋ง๋ค์ด ๋๊ฑฐ๋ ์๋ก ์์ฑํ ์ธ์คํด์ค๋ฅผ ์บ์ฑํ์ฌ ์ฌํ์ฉ ํ๋์์ผ๋ก ๋ถํ์ํ ๊ฐ์ฒด ์์ฑ์ ํ์ง ์๋๋ค. ๋ฐ๋ผ์ ๊ฐ์ ๊ฐ์ฒด๊ฐ ์์ฃผ ์์ฒญ๋๋ ์ํฉ์์ ์ฑ๋ฅ ํจ๊ณผ๊ฐ ๋ฐ์ด๋๋ค. *ํ๋ผ์ด์จ์ดํธ ํจํด(Flyweight pattern)๋ ์ด์ ๋น์ทํ ๊ธฐ๋ฒ์ด๋ค. ex) Boolean.valueOf(boolean) public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false); public static Boolean valueOf(boolean var0) { return var0 ? TRUE : FALSE; } 2. ๋ฐ๋ณต๋๋ ์์ฒญ์ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ์์ผ๋ก ์ธ์ ์ด๋ ์ธ์คํด์ค๋ฅผ ์ด์ ์๊ฒ ํ ์ง๋ฅผ ์ฒ ์ ํ ํต์ ํ ์ ์๋ค. ์ด๋ฐ ํต์ ๋ฅผ ์ธ์คํด์ค ํต์ ํด๋์ค๋ผ ํ๋ค. ์ธ์คํด์ค๋ฅผ ํต์ ํ๋ฉด ์ฑ๊ธํด(์์ดํ 3)์ผ๋ก ๋ฐ๋ค ์๋, ์ธ์คํด์คํ ๋ถ๊ฐ(์์ดํ 4)๋ก ๋ง๋ค ์ ์๋ค. ๋ํ ๋ถ๋ณ ๊ฐ ํด๋์ค(์์ดํ 17)์์ ๋์น์ธ ์ธ์คํด์ค๊ฐ ๋จ ํ๋๋ฟ ์์ ๋ณด์ฅํ ์ ์๋ค.( a == b์ผ ๋๋ง a.equals(b) ๊ฐ ์ฑ๋ฆฝ) ์ธ์คํด์ค ํต์ ๋ ํ๋ผ์ด์จ์ดํธ ํจํด์ ๊ทผ๊ฐ์ด ๋๋ค. ์ด๊ฑฐ ํ์ (์์ดํ 34)์ ์ธ์คํด์ค๊ฐ ํ๋๋ง ๋ง๋ค์ด์ง์ ๋ณด์ฅํ๋ค. |
์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ ํ๋ก๊ทธ๋๋จธ๊ฐ ์ฐพ๊ธฐ ์ด๋ ต๋ค. ์์ฑ์์ ๊ฐ์ด ๋ช ํํ ๋๋ฌ๋์ง ์์ผ๋ ์ฌ์ฉ์๋ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋ ๋ฐฉ์ ํด๋์ค๋ฅผ ์ธ์คํด์คํํ ๋ฐฉ๋ฒ์ ์์์ผ ํ๋ค. (์ฌ์ฉ ํ๋ ๋ฉ์๋๊ฐ ์ ์ ํฉํ ๋ฆฌ์ธ์ง ํ์ธํ ๋ฐฉ๋ฒ?) ๋ฐ๋ผ์ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋์ ํํ ์ฌ์ฉํ๋ ๋ช ๋ช ๋ฐฉ์์ผ๋ก ๊ท์ฝ์ ๋ฐ๋ผ ์ง๋๋ค. - from : ๋งค๊ฒ ๋ณ์๋ฅผ ํ๋ ๋ฐ์ ํด๋น ํ์ ์ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ ํ ๋ณํ ๋ฉ์๋ Date d = Date.from(Instant.now());
- of: ์ฌ๋ฌ ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ์ ์ ํฉํ ํ์ ์ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ ์ง๊ณ ๋ฉ์๋ Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING);
- valueOf: from ๊ณผ of์ ๋ ์์ธํ ๋ฒ์ BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
- instance ํน์ getInstance: ๋งค๊ฐ๋ณ์๋ก ๋ช ์ํ ์ธ์คํด์ค๋ฅผ ๋ฐํํ์ง๋ง, ๊ฐ์ ์ธ์คํฐ์์ ๋ณด์ฅํ์ง๋ ์๋๋ค. StackWalker luke = StackWalker.getInstance(options);
- create ํน์ newInstance : instance ํน์ getInstance์ ๊ฐ์ง๋ง, ๋งค๋ฒ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์์ฑํด ๋ฐํํจ์ ๋ณด์ฅํ๋ค. Object newArray = Array.newInstance(classObject, arrayLen);
- getType : getInstance์ ๊ฐ์ผ๋, ์์ฑํ ํด๋์ค๊ฐ ์๋ ๋ค๋ฅธ ํด๋์ค์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ฅผ ์ ์ํ ๋ ์ด๋ค. "Type"์ ํฉํฐ๋ฆฌ ๋ฉ์๋๊ฐ ๋ฐํํ ๊ฐ์ฒด์ ํ์ ์ด๋ค. FileStore fs = Files.getFileStore(path);
- newType: newInstance์ ๊ฐ์ผ๋, ์์ฑํ ํด๋์ค๊ฐ ์๋ ๋ค๋ฅธ ํด๋์ค์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ฅผ ์ ์ํ ๋ ์ด๋ค. "Type"์ ํฉํฐ๋ฆฌ ๋ฉ์๋๊ฐ ๋ฐํํ ๊ฐ์ฒด์ ํ์ ์ด๋ค. BufferedReader br = Files.newBufferedReader(path);
- type: getType๊ณผ newType์ ๊ฐ๊ฒฐํ ๋ฒ์ List<Complaint> litany = Collections.list(legacyLitany);
|
๋ฐํ ํ์
์ ํ์ ํ์
๊ฐ์ฒด๋ฅผ ๋ฐํํ ์ ์๋ ๋ฅ๋ ฅ์ด ์๋ค. 1. ๊ตฌํ ํด๋์ค๋ฅผ ๊ณต๊ฐํ์ง ์๊ณ ๋ ๊ฐ์ฒด ๋ฐํ์ ํ ์ ์์ด API๋ฅผ ์๊ฒ ์ ์งํ ์ ์๋ค. ์ด๋ ์ธํฐํ์ด์ค๋ฅผ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋์ ๋ฐํ ํ์ ์ผ๋ก ์ฌ์ฉํ๋ ์ธํฐํ์ด์ค ๊ธฐ๋ฐ ํ๋ ์์ํฌ(์์ดํ 20)๋ฅผ ๋ง๋๋ ํต์ฌ ๊ธฐ์ ์ด๊ธฐ๋ ํ๋ค. |
|
์
๋ ฅ ๋งค๊ฐ๋ณ์์ ๋ฐ๋ผ ๋งค๋ฒ ๋ค๋ฅธ ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ ์ ์๋ค. ๋ฐํ ํ์ ์ ํ์ ํ์ ์ด๊ธฐ๋ง ํ๋ฉด ์ด๋ค ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ์๊ด ์๋ค. ๊ฐ๋ น EnumSet ํด๋์ค(์์ดํ 36)๋ public ์์ฑ์ ์์ด ์ค์ง ์ ์ ํฉํฐ๋ฆฌ๋ง ์ ๊ณตํ๋๋ฐ ์์์ ์์ ๋ฐ๋ผ ๋๊ฐ์ง ํ์ ํด๋์ค ์ค ํ๋์ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ค. ์์๊ฐ 64๊ฐ ์ดํ๋ฉด long ๋ณ์ ํ๋๋ก ๊ด๋ฆฌํ๋ RegularEnumSet์ ์ธ์คํด์ค๋ฅผ, 65๊ฐ ์ด์์ด๋ฉด long ๋ฐฐ์ด๋ก ๊ด๋ฆฌํ๋ JumboEnumSet์ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ค. public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> var0) {
Enum[] var1 = getUniverse(var0); if (var1 == null) { throw new ClassCastException(var0 + " not an enum"); } else { return (EnumSet)(var1.length <= 64 ? new RegularEnumSet(var0, var1) : new JumboEnumSet(var0, var1)); } } ํด๋ผ์ด์ธํธ๋ ์์ ๋ ํด๋์ค์ ์กด์ฌ๋ฅผ ๋ชจ๋ฅธ๋ค. ์ํ์๋ ์๋ค. EnumSet์ ํ์ ํด๋์ค์ด๊ธฐ๋ง ํ๋ฉด ๋๋ ๊ฒ์ด๋ค. |
|
์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ฅผ ์์ฑํ๋ ์์ ์๋ ๋ฐํํ ๊ฐ์ฒด์ ํด๋์ค๊ฐ ์กด์ฌํ์ง ์์๋ ๋๋ค. ๋ํ์ ์ผ๋ก JDBC ๋๋ผ์ด๋ฒ ํด๋์ค๋ฅผ ๋ก๋ํ๊ธฐ ์ํด Class.forName()์ ์ฌ์ฉํ๋ค. ํด๋์ค ์ด๋ฆ์ ๋ฌธ์์ด๋ก ๋ฐ์ ๋ฐํ ํ์ ์ผ๋ก Class ๊ฐ์ฒด๋ฅผ ๋ฐ์ ์ ์๋ค. ์ด๋ฅผ ํตํด ํด๋ผ์ด์ธํธ๋ JDBC ๋๋ผ์ด๋ฒ ํด๋์ค๋ฅผ ๋ณ๊ฒฝํ ํ์ ์์ด Class.forName()๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ก๋ํ ์ ์๋ค. try {
Class<?> testClass = Class.forName("test"); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } ex) class LoggerFactory {
private LoggerFactory() { // private constructor } public static Logger getLogger(Class clazz) { // implementation } public static Logger getLogger(String name) { // implementation } } public class Main { private static final Logger logger = LoggerFactory.getLogger(Main.class); public static void main(String[] args) { logger.info("Hello, world!"); } } LoggerFactory๋ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ logger ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. ํด๋์ค์ ์ด๋ฆ์ด๋ ๋ฌธ์์ด ์ด๋ฆ์ ์ฌ์ฉํ์ฌ ์์ฑ ํ ์ ์๋ค. |
ํต์ฌ ์ ๋ฆฌ
์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋์ public ์์ฑ์๋ ๊ฐ์์ ์ฐ์์๊ฐ ์์ผ๋ ์๋์ ์ธ ์ฅ๋จ์ ์ ์ดํดํ๊ณ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. ๊ทธ๋ ๋ค๊ณ ํ๋๋ผ๋ ์ ์ ํฉํฐ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ์ ๋ฆฌํ ๊ฒฝ์ฐ๊ฐ ๋ ๋ง์ผ๋ฏ๋ก ๋ฌด์์ public ์์ฑ์๋ฅผ ์ ๊ณตํ๋ ์ต๊ด์ด ์๋ค๋ฉด ๊ณ ์น์
.์์ดํ 2 - ์์ฑ์์ ๋งค๊ฐ๋ณ์๊ฐ ๋ง๋ค๋ฉด ๋น๋๋ฅผ ๊ณ ๋ คํ๋ผ.
๋งค๊ฐ๋ณ์๊ฐ ๋ง์ ๋ ํ์ฉํ๋ ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ์๋ค.
- ์ ์ธต์ ์์ฑ์ ํจํด
this(servingSize, servings, 0);
}
public NutritionFacts(int servingSize, int servings, int calories) {
this(servingSize, servings, calories, 0);
}
public NutritionFacts(int servingSize, int servings, int calories, int fat) {
this(servingSize, servings, calories, fat, 0);
}
public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium) {
this(servingSize, servings, calories, fat, sodium, 0);
}
์ ์ธต์ ์์ฑ์ ํจํด์ ๋งค๊ฐ๋ณ์ ๊ฐ์๊ฐ ๋ง์์ง๋ฉด ํด๋ผ์ด์ธํธ ์ฝ๋๋ฅผ ์์ฑํ๊ฑฐ๋ ์ฝ๊ธฐ ์ด๋ ต๋ค.
- ์๋ฐ๋น์ฆ ํจํด
public void setServingSize(int servingSize) {
this.servingSize = servingSize;
}
public void setServings(int servings) {
this.servings = servings;
}
public void setCalories(int calories) {
this.calories = calories;
}
public void setFat(int fat) {
this.fat = fat;
}
public void setSodium(int sodium) {
this.sodium = sodium;
}
public void setCarbohydrate(int carbohydrate) {
this.carbohydrate = carbohydrate;
}
nutritionFacts2.setServingSize(1);
nutritionFacts2.setServings(2);
nutritionFacts2.setCalories(3);
nutritionFacts2.setFat(4);
nutritionFacts2.setSodium(5);
nutritionFacts2.setCarbohydrate(6);
์๋ฐ ๋น์ฆ ํจํด์ ๊ฐ์ฒด ํ๋๋ฅผ ๋ง๋ค๊ธฐ ์ํด ์ฌ๋ฌ ๋ฉ์๋๋ฅผ ํธ์ถํด์ผ ํ๊ณ , ๊ฐ์ฒด๊ฐ ์์ ํ ์์ฑ๋๊ธฐ ์ ๊น์ง๋ ์ผ๊ด์ฑ์ด ๋ฌด๋์ง ์ํ์ ๋์ธ๋ค.
- ๋น๋ ํจํด
์ ์ธต์ ์์ ์ ํจํด์ ์์ ์ฑ๊ณผ ์๋ฐ๋น์ฆ ํจํด์ ๊ฐ๋ ์ฑ์ ๊ฒธ๋นํ ํจํด.
๋น๋๋ ์์ฑํ ํด๋์ค ์์ ์ ์ ๋ฉค๋ฒ ํด๋์ค๋ก ๋ง๋ค์ด ๋๋ ๊ฒ ๋ณดํต์ด๋ค.
// ํ์ ๋งค๊ฐ๋ณ์
private final int servingSize; // (mL, 1ํ ์ ๊ณต๋) ํ์
private final int servings; // (ํ, ์ด nํ ์ ๊ณต๋) ํ์
// ์ ํ ๋งค๊ฐ๋ณ์ - ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ด๊ธฐํํ๋ค.
private int calories = 0; // (1ํ ์ ๊ณต๋๋น) ์ ํ
private int fat = 0; // (g/1ํ ์ ๊ณต๋) ์ ํ
private int sodium = 0; // (mg/1ํ ์ ๊ณต๋) ์ ํ
private int carbohydrate = 0;// (g/1ํ ์ ๊ณต๋) ์ ํ
public Builder(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(int val) {
calories = val;
return this;
}
public Builder fat(int val) {
fat = val;
return this;
}
public Builder sodium(int val) {
sodium = val;
return this;
}
public Builder carbohydrate(int val) {
carbohydrate = val;
return this;
}
public NutritionFacts build() {
return new NutritionFacts(this);
}
}
.calories(3)
.fat(4)
.sodium(5)
.carbohydrate(6)
.build();
NutritionFacts ํด๋์ค๋ ๋ถ๋ณ์ด๋ฉฐ, ๋ชจ๋ ๋งค๊ฐ๋ณ์์ ๊ธฐ๋ณธ๊ฐ๋ค์ ํ ๊ณณ์ ๋ชจ์ ๋์๋ค. ๋น๋์ ์ธํฐ ๋ฉ์๋ค์ ์๊ธฐ ์์ ์ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ์ฐ์์ ์ผ๋ก ํธ์ถ์ด ๊ฐ๋ฅํ๋ค (๋ฉ์๋ ์ฒด์ด๋)
๋น๋ ํจํด์ (ํ์ด์ฌ, ์ค์นผ๋ผ์ ์๋) ๋ช ๋ช ๋ ์ ํ์ ๋งค๊ฐ๋ณ์๋ฅผ ํ๋ด ๋ธ ๊ฒ์ด๋ค.
๋น๋ ํจํด์ ๊ณ์ธต์ ์ผ๋ก ์ค๊ณ๋ ํด๋์ค์ ํจ๊ป ์ฐ๊ธฐ ์ข๋ค.
ํต์ฌ ์ ๋ฆฌ
์์ฑ์๋ ์ ์ ํฉํฐ๋ฆฌ๊ฐ ์ฒ๋ฆฌํด์ผ ํ ๋งค๊ฐ๋ณ์๊ฐ ๋ง๋ค๋ฉด ๋น๋ ํจํด์ ์ ํํ๋ ๊ฒ ๋ ๋ซ๋ค.
๋งค๊ฐ ๋ณ์ ์ค ๋ค์๊ฐ ํ์๊ฐ ์๋๊ฑฐ๋ ๊ฐ์ ํ์ ์ด๋ฉด ํนํ ๋ ๊ทธ๋ ๋ค. ๋น๋๋ ์ ์ธต์ ์์ฑ์๋ณด๋ค ํด๋ผ์ด์ธํธ ์ฝ๋๋ฅผ ์ฝ๊ณ ์ฐ๊ธฐ๊ฐ ํจ์ฌ ๊ฐ๊ฒฐํ๊ณ , ์๋ฐ๋น์ฆ๋ณด๋ค ํจ์ฌ ์์ ํ๋ค.
.์์ดํ 3 - private ์์ฑ์๋ ์ด๊ฑฐ ํ์ ์ผ๋ก ์ฑ๊ธํด์์ ๋ณด์ฆํ๋ผ.
์ฑ๊ธํด์ด๋ ์ธ์คํด์ค๋ฅผ ์ค์ง ํ๋๋ง ์์ฑํ ์ ์๋ ํด๋์ค์ด๋ค.
์ ํ์ ์ธ ์๋ก ํจ์(์์ดํ 24)์ ๊ฐ์ ๋ฌด์ํ(stateless) ๊ฐ์ฒด๋ ์ค๊ณ์ ์ ์ผํด์ผ ํ๋ ์์คํ ์ปดํฌ๋ํธ๋ฅผ ๋ค ์ ์๋ค.
๊ทธ๋ฐ๋ฐ ํด๋์ค๋ฅผ ์ฑ๊ธํด์ผ๋ก ๋ง๋ค ๊ฒฝ์ฐ ์ด๋ฅผ ์ฌ์ฉํ๋ ํด๋ผ์ด์ธํธ๋ฅผ ํ ์คํธํ๊ธฐ๊ฐ ์ด๋ ต๋ค. ํ์ ์ ์ธํฐํ์ด์ค๋ก ์ ์ํ ๋ค์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ ๋ง๋ ์ฑ๊ธํด์ด ์๋๋ผ๋ฉด ์ฑ๊ธํด ์ธ์คํด์ค๋ฅผ ๊ฐ์ง(Mock) ๊ตฌํ์ผ๋ก ๋์ฒดํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ฑ๊ธํด์ ๋ง๋๋ ๋ฐฉ์์ ๋ณดํต ๋ ๊ฐ์ง๋ก ๋๋๋ค.
๋ ๋ฐฉ์ ๋ชจ๋ ์์ฑ์๋ private๋ก ๊ฐ์ถฐ๋๊ณ , ์ ์ผํ ์ธ์คํด์ค์ ์ ๊ทผํ ์ ์๋ ์๋จ์ผ๋ก public static ๋ฉค๋ฒ๋ฅผ ํ๋ ๋ง๋ จํด ๋๋ค.
- public static ๋ฉค๋ฒ final ํ๋์ธ ๋ฐฉ์
public static final Elvis INSTANCE = new Elvis();
private Elvis() {
}
public void leaveTheBuilding() {
System.out.println("Elvis has left the building.");
}
}
private ์์ฑ์๋ Elvis.INSTANCE๋ฅผ ์ด๊ธฐํํ ๋ ๋จ ํ ๋ฒ๋ง ํธ์ถ๋๋ค.
public, protected ์์ฑ์๊ฐ ์์ผ๋ฏ๋ก ์ ์ฒด ์์คํ ์์ ํ๋๋ฟ์์ ๋ณด์ฅํ๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ์์ธ ๋ฐฉ๋ฒ์ ๋ฆฌํ๋ ์ API(์์ดํ 65)์ธ AccessibleObject.setAccessible์ ์ฌ์ฉํด ํธ์ถํ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ด๋ฌํ ๋ฆฌํ๋ ์ ๊ณต๊ฒฉ์ ๋ฐฉ์ดํ๋ ค๋ฉด ์์ฑ์๋ฅผ ์์ ํ์ฌ ๋ ๋ฒ์งธ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ ค ํ ๋ ์์ธ๋ฅผ ๋์ง๊ฒ ํ๋ฉด ๋๋ค.
- ์ฅ์
1. ํด๋น ํด๋์ค๊ฐ ์ฑ๊ธํด์์ด ๋ช ๋ฐฑํ ๋๋ฌ๋๋ค.
2. ๊ฐ๊ฒฐํจ
- ์ ์ ํฉํฐ๋ฆฌ ๋ฐฉ์์ ์ฑ๊ธํด
public static Elvis getInstance() {
return INSTANCE2;
}
public void leaveTheBuilding2() {
System.out.println("Elvis has left the building.");
}
Elvis.getInstance๋ ํญ์ ๊ฐ์ ๊ฐ์ฒด์ ์ฐธ์กฐ๋ฅผ ๋ฐํํ๋ฏ๋ก ์ 2์ Elvis ์ธ์คํด์ค๋ ๊ฒฐ์ฝ ๋ง๋ค์ด์ง์ง ์๋๋ค. (์์ ๋ฐฉ์๊ณผ ๊ฐ์ด ๋ฆฌํ๋ ์ ์์ธ๋ ๋๊ฐ์ด ์ ์ฉ)
- ์ฅ์
1. API๋ฅผ ๋ฐ๊พธ์ง ์๊ณ ๋ ์ฑ๊ธํด์ด ์๋๊ฒ ๋ณ๊ฒฝํ ์ ์๋ค. - ์ค๋ ๋ ๋ณ๋ก ๋ค๋ฅธ ์ธ์คํด์ค ๋ฐํ ๊ฐ๋ฅ
2. ์ ์ ํฉํฐ๋ฆฌ๋ฅผ ์ ๋ค๋ฆญ ์ฑ๊ธํด ํฉํฐ๋ฆฌ๋ก ๋ง๋ค ์ ์๋ค (์์ดํ 30)
3. ์ ์ ํฉํฐ๋ฆฌ์ ๋ฉ์๋ ์ฐธ์กฐ๋ฅผ ๊ณต๊ธ์(supplier)๋ก ์ฌ์ฉํ ์ ์๋ค. - Elvis::getInstance -> Supplier<Elvis> (์์ดํ 43, 44)
๋ ์ค ํ๋์ ๋ฐฉ์์ผ๋ก ๋ง๋ ์ฑ๊ธํด ํด๋์ค๋ฅผ ์ง๋ ฌํํ๋ ค๋ฉด(12์ฅ ์ฐธ์กฐ) ๋จ์ํ Serializable์ ๊ตฌํํ๋ค๊ณ ์ ์ธํ๋ ๊ฒ๋ง์ผ๋ก ๋ถ์กฑํ๋ค.
๋ชจ๋ ์ธ์คํด์ค ํ๋๋ฅผ ์ผ์์ (transient)์ด๋ผ๊ณ ์ ์ธํ๊ณ readResolve ๋ฉ์๋๋ฅผ ์ ๊ณตํด์ผ ํ๋ค(์์ดํ 89) ์ด๋ ๊ฒ ํ์ง ์์ผ๋ฉด ์ง๋ ฌํ๋ ์ธ์คํด์ค๋ฅผ ์ญ์ง๋ ฌํํ ๋๋ง๋ค ์๋ก์ด ์ธ์คํด์ค๊ฐ ๋ง๋ค์ด์ง๋ค.
๊ฐ์ง Elvis ํ์์ ์๋ฐฉํ๊ณ ์ถ๋ค๋ฉด Elvis ํด๋์ค์ ๋ค์์ readResolve ๋ฉ์๋๋ฅผ ์ถ๊ฐํ์.
// '์ง์ง' Elvis๋ฅผ ๋ฐํํ๊ณ , ๊ฐ์ง Elvis๋ ๊ฐ๋น์ง ์ปฌ๋ ํฐ์ ๋งก๊ธด๋ค.
return INSTANCE;
}
- ์ด๊ฑฐ ํ์ ๋ฐฉ์์ ์ฑ๊ธํด - ๋ฐ๋์งํ ๋ฐฉ๋ฒ
public ํ๋ ๋ฐฉ์๊ณผ ๋น์ทํ์ง๋ง, ๋ ๊ฐ๊ฒฐํ๊ณ ์ถ๊ฐ ๋ ธ๋ ฅ ์์ด ์ง๋ ฌํํ ์ ์๊ณ , ์ฌ์ง์ด ์์ฃผ ๋ณต์กํ ์ง๋ ฌํ ์ํฉ์ด๋ ๋ฆฌํ๋ ์ ๊ณต๊ฒฉ์์๋ ์ 2์ ์ธ์คํด์ค๊ฐ ์๊ธฐ๋ ์ผ์ ์๋ฒฝํ ๋ง์์ค๋ค.
๋๋ถ๋ถ์ ์ํฉ์์๋ ์์๊ฐ ํ๋๋ฟ์ธ ์ด๊ฑฐ ํ์ ์ด ์ฑ๊ธํด์ ๋ง๋๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ด๋ค.
๋จ, ๋ง๋ค๋ ค๋ ์ฑ๊ธํด์ด Enum ์ธ์ ํด๋์ค๋ฅผ ์์ํด์ผ ํ๋ค๋ฉด ์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ์ ์๋ค.(์ด๊ฑฐ ํ์ ์ด ๋ค๋ฅธ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋๋ก ์ ์ธํ ์๋ ์๋ค.).
.์์ดํ 4 - ์ธ์คํด์คํ๋ฅผ ๋ง์ผ๋ ค๊ฑฐ๋ private ์์ฑ์๋ฅผ ์ฌ์ฉํ๋ผ
์ด๋ฐ๊ธ ๋จ์ํ ์ ์ ๋ฉ์๋์ ์ ์ ํ๋๋ง์ ๋ด์ ํด๋์ค๋ฅผ ๋ง๋ค๊ณ ์ถ์ ๋์ด๋ค.
1. java.lang.Math ์ java.util.Arrays์ฒ๋ผ ๊ธฐ๋ณธ ํ์ ๊ฐ์ด๋ ๋ฐฐ์ด ๊ด๋ จ ๋ฉ์๋๋ค์ ๋ชจ์๋์ ์ ์๋ค.
2. java.util.Collections์ฒ๋ผ ํน์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ๊ฐ์ฒด๋ฅผ ์์ฑํด ์ฃผ๋ ์ ์ ๋ฉ์๋(ํน์ ํฉํฐ๋ฆฌ)๋ฅผ ๋ชจ์ ๋์ ์ ์๋ค.
3. final ํด๋์ค์ ๊ด๋ จํ ๋ฉ์๋ค์ ๋ชจ์ ๋์ ๋ ์ฌ์ฉํ๋ค. final ํด๋์ค๋ฅผ ์์ํด์ ํ์ ํด๋์ค์ ๋ฉ์๋๋ฅผ ๋ฃ๋ ๊ฑด ๋ถ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ ์ ๊ฐ์ด ์ ์ ๋ฉค๋ฒ๋ง ๋ด์ ์ ํธ ํด๋์ค๋ ์ธ์คํด์ค๋ก ๋ง๋ค์ด ์ฌ์ฉํ๊ณ ์ ํ ๊ฒ ์๋๋ค. ํ์ง๋ง ์์ฑ์๋ฅผ ๋ช ์ํ์ง ์์ผ๋ฉด ์ปดํ์ผ๋ฌ๊ฐ ์๋์ผ๋ก public ๊ธฐ๋ณธ ์์ฑ์๋ฅผ ๋ง๋ค์ด์ค๋ค.
์ถ์ ํด๋์ค๋ก ๋ง๋๋ ๊ฒ์ผ๋ก๋ ์ธ์คํด์คํ๋ฅผ ๋ง์ ์ ์๋ค. ํ์ ํด๋์ค๋ฅผ ๋ง๋ค์ด ์ธ์คํด์คํํ๋ฉด ๊ทธ๋ง์ด๋ค. ๋ค๋ฅธ ์ฌ์ฉ์๊ฐ ์์ํด์ ์ฌ์ฉํ๋ผ๋ ๋ป์ผ๋ก ์คํดํ ์ ์์ผ๋ ํฐ ๋ฌธ์ ๋ค(์์ดํ 19).
๋๋ฌธ์ private์ผ๋ก ์์ฑ์๋ฅผ ์ถ๊ฐํ๋ฉด ์ปดํ์ผ๋ฌ๊ฐ public ๊ธฐ๋ณธ ์์ฑ์๋ฅผ ๋ง๋ค์ง ์์ ํด๋์ค์ ์ธ์คํด์คํ๋ฅผ ๋ง์ ์ ์๋ค.
.์์ดํ 5 - ์์์ ์ง์ ๋ช ์ํ์ง ๋ง๊ณ ์์กด ๊ฐ์ฒด ์ฃผ์ ์ ์ฌ์ฉํ๋ผ
๋ง์ ํด๋์ค๊ฐ ํ๋ ์ด์์ ์์์ ์์กดํ๋ค. ๊ฐ๋ น ๋ง์ถค๋ฒ ๊ฒ์ฌ๊ธฐ๋ ์ฌ์ (dictionary)์ ์์กดํ๋๋ฐ, ์ด๋ฐ ํด๋์ค๋ฅผ ์ ์ ์ ํธ๋ฆฌํฐ ํด๋์ค(์์ดํ 4)๋ก ๊ตฌํํ ๋ชจ์ต์ ๋๋ฌผ์ง ์๊ฒ ๋ณผ ์ ์๋ค.
๋์ ํด๋์ค(SpellChecker)๊ฐ ์ฌ๋ฌ ์์ ์ธ์คํด์ค๋ฅผ ์ง์ํด์ผ ํ๋ฉฐ, ํด๋ผ์ด์ธํธ๊ฐ ์ํ๋ ์์(dictionary)์ ์ฌ์ฉํด์ผ ํ๋ค.
์ด๋ฅผ ๋ง์กฑํ๋ ๊ฐ๋จํ ์กฐ๊ฑด์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋ ์์ฑ์์ ํ์ํ ์์์ ๋๊ฒจ์ค๋ค. ์ด๋ ์์กด ๊ฐ์ฒด ์ฃผ์ ์ ํ ํํ์ด๋ค.
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) { // ์์กด ๊ฐ์ฒด ์ฃผ์
this.dictionary = Objects.requireNonNull(dictionary);
}
public boolean isValid(String word){
return true;
}
public static List<String> suggestions(String typo){
return new ArrayList<>();
}
}
ํต์ฌ ์ ๋ฆฌ
ํด๋์ค๊ฐ ๋ด๋ถ์ ์ผ๋ก ํ๋ ์ด์์ ์์์ ์์กดํ๊ณ , ๊ทธ ์์์ด ํด๋์ค ๋์์ ์ํฅ์ ์ค๋ค๋ฉด ์ฑ๊ธํด๊ณผ ์ ์ ์ ํธ๋ฆฌํฐ ํด๋์ค๋ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์ข๋ค. ์ด ์์๋ค์ ํด๋์ค๊ฐ ์ง์ ๋ง๋ค๊ฒ ํด์๋ ์ ๋๋ค.
๋์ ํ์ํ ์์์ ์์ฑ์์ ๋๊ฒจ์ฃผ์. ์์กด ๊ฐ์ฒด ์ฃผ์ ์ด๋ผ ํ๋ ์ด ๊ธฐ๋ฒ์ ํด๋์ค์ ์ ์ฐ์ฑ, ์ฌ์ฌ์ฉ์ฑ, ํ ์คํธ ์ฉ์ด์ฑ์ ๊ฐ์ ํด ์ค๋ค.
.์์ดํ 6 - ๋ถํ์ํ ๊ฐ์ฒด ์์ฑ์ ํผํ๋ผ
๋๊ฐ์ ๊ธฐ๋ฅ์ ๊ฐ์ฒด๋ฅผ ๋งค๋ฒ ์์ฑํ๊ธฐ๋ณด๋ค๋ ๊ฐ์ฒด ํ๋๋ฅผ ์ฌ์ฌ์ฉํ๋ ํธ์ด ๋์ ๋๊ฐ ๋ง๋ค. ์ฌ์ฌ์ฉ์ ๋น ๋ฅด๊ณ ์ธ๋ จ๋๋ค.
ํนํ ๋ถ๋ณ ๊ฐ์ฒด(์์ดํ 17)๋ ์ธ์ ๋ ์ฌ์ฌ์ฉํ ์ ์๋ค.
return s.matches("^(?=.)M*(C[MD]|D?C{0,3})" + "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
}
์ ๋ฐฉ์์ String.matches๋ก ์ ๊ทํํ์์ ํ์ฉํ ๋ฉ์๋์ด๋ค.
๋ฌธ์ ์ ์ผ๋ก๋ String.matches๋ ์ ๊ทํํ์์ผ๋ก ๋ฌธ์์ด ํํ๋ฅผ ํ์ธํ๋ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ด์ง๋ง, ์ฑ๋ฅ์ด ์ค์ํ ์ํฉ์์ ๋ฐ๋ณตํด ์ฌ์ฉํ๊ธฐ์ ์ ํฉํ์ง ์๋ค.
์ด ๋ฉ์๋๊ฐ ๋ด๋ถ์์ ๋ง๋๋ ์ ๊ทํํ์์ฉ Pattern ์ธ์คํด์ค๋, ํ ๋ฒ ์ฐ๊ณ ๋ฒ๋ ค์ ธ์ ๊ณง๋ฐ๋ก ๊ฐ๋น์ง ์ปฌ๋ ์ ๋์์ด ๋๋ค.
Pattern์ ์ ๋ ฅ๋ฐ์ ์ ๊ทํํ์์ ํด๋นํ๋ ์ ํ ์ํ ๋จธ์ ์ ๋ง๋ค๊ธฐ ๋๋ฌธ์ ์ธ์คํด์ค ์์ฑ ๋น์ฉ์ด ๋๋ค.
return Pattern.matches(var1, this);
}
Pattern var2 = compile(var0);
Matcher var3 = var2.matcher(var1);
return var3.matches();
}
return new Pattern(var0, 0);
}
๋ฐ๋ผ์ ์ฑ๋ฅ ๊ฐ์ ์ ์ํด ํ์ํ ์ ๊ทํํ์์ ํํํ๋ Pattern ์ธ์คํด์ค๋ฅผ ํด๋์ค ์ด๊ธฐํ ๊ณผ์ ์์ ์ง์ ์์ฑํด ์บ์ฑํด ๋๊ณ , ๋์ค์ isRomanNumeral ๋ฉ์๋๊ฐ ํธ์ถ๋ ๋๋ง๋ค ์ด ์ธ์คํด์ค๋ฅผ ์ฌ์ฌ์ฉํ๋ค.
private static final Pattern ROMAN = Pattern.compile(
"^(?=.)M*(C[MD]|D?C{0,3})" +
"(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$"
);
/* String.matches */
static boolean isRomanNumeral(String s){
return ROMAN.matcher(s).matches();
}
}
๋ง์ผ ๊ฐ์ ๋ isRomanNumberal ๋ฐฉ์์ ํด๋์ค๊ฐ ์ด๊ธฐํ ํ ํ ๋ฒ๋ ํธ์ถ๋์ง ์๋๋ค๋ฉด ๋ถํ์ํ ์ด๊ธฐํ๊ฐ ๋ ๊ผด์ด๋ค.
์ด๋ฅผ ์ํด ์ง์ฐ ์ด๊ธฐํ(์์ดํ 83)๋ก ์์จ ์๋ ์์ง๋ง , ๊ถํ์ง๋ ์๋๋ค.
์ง์ฐ ์ด๊ธฐํ๋ ์ฝ๋๋ฅผ ๋ณต์กํ๊ฒ ๋ง๋๋๋ฐ, ์ฑ๋ฅ์ ํฌ๊ฒ ๊ฐ์ ๋์ง ์์ ๋๊ฐ ๋ง๊ธฐ ๋๋ฌธ์ด๋ค.(์์ดํ 67)
๋ถํ์ํ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด๋ด๋ ๋ ๋ค๋ฅธ ์๋ก ์คํ ๋ฐ์ฑ์ ๋ค ์ ์๋ค.
์คํ ๋ฐ์ฑ์ ๊ธฐ๋ณธ ํ์ ๊ณผ ๊ทธ์ ๋์ํ๋ ๋ฐ์ฑ ๋ ๊ธฐ๋ณธ ํ์ ์ ๊ตฌ๋ถ์ ํ๋ ค์ฃผ์ง๋ง, ์์ ํ ์์ ์ฃผ๋ ๊ฒ์ ์๋๋ค.
Long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
return sum;
}
์์ ์ฝ๋๋ sum ๋ณ์๋ฅผ long ์ด ์๋ Long์ผ๋ก ์ ์ธํด์ ๋ถํ์ํ ์ธ์คํด์ค๊ฐ Integer.Max_Value ๊ฐ์๋งํผ ๋ง๋ค์ด์ง๋ค.
๋จ์ํ sum ํ์ ์ long์ผ๋ก๋ง ๋ฐ๊ฟ์ฃผ๋ฉด ๋นจ๋ผ์ง๋ค.
๋ฐ์ฑ๋ ๊ธฐ๋ณธ ํ์ ๋ณด๋ค๋ ๊ธฐ๋ณธํ์ ์ ์ฌ์ฉํ๊ณ , ์๋์น ์์ ์คํ ๋ฐ์ฑ์ด ์จ์ด๋ค์ง ์๋๋ก ์ฃผ์ํ์.
์ด๋ฒ ์์ดํ ์ ๋ฐฉ์ด์ ๋ณต์ฌ(์์ดํ 50)์ ๋์กฐ์ ์ด๋ค.
์ด๋ฒ ์์ดํ ์ด '๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ์ฌ์ฌ์ฉํด์ผ ํ๋ค๋ฉด ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ง ๋ง๋ผ' ๋ผ๋ฉด, ๋ฐฉ์ด์ ๋ณต์ฌ(์์ดํ 50)๋ '์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค๋ฉด ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ์ฌ์ฌ์ฉํ์ง ๋ง๋ผ'๋ค.
๋ฐฉ์ด์ ๋ณต์ฌ๊ฐ ํ์ํ ์ํฉ์์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฌ์ฉํ์ ๋์ ํผํด๊ฐ, ํ์ ์๋ ๊ฐ์ฒด๋ฅผ ๋ฐ๋ณต ์์ฑํ์ ๋์ ํผํด๋ณด๋ค ํจ์ฌ ํฌ๋ค๋ ์ฌ์ค์ ๊ธฐ์ตํ์.
๋ฐฉ์ด์ ๋ณต์ฌ์ ์คํจํ๋ฉด ๋ฒ๊ทธ์ ๋ณด์ ๊ตฌ๋ฉ์ด ์๊ธฐ์ง๋ง, ๋ถํ์ํ ๊ฐ์ฒด ์์ฑ์ ๊ทธ์ ์ฝ๋ํํ์ ์ฑ๋ฅ์ ์ํฅ์ ์ค๋ค.
.์์ดํ 7 - ๋ค ์ด ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ํด์ ํ๋ผ.
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
this.elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e){
ensureCapacity();
elements[size++] = e;
}
public Object pop(){
if(size == 0)
throw new EmptyStackException();
Object result = elements[--size];
return result;
}
/**
* ์์๋ฅผ ์ํ ๊ณต๊ฐ์ ์ ์ด๋ ํ๋ ์ด์ ํ๋ณดํ๋ค.
* ๋ฐฐ์ด ํฌ๊ธฐ๋ฅผ ๋๋ ค์ผ ํ ๋๋ง๋ค ๋๋ต ๋ ๋ฐฐ์ฉ ๋๋ฆฐ๋ค.
*/
private void ensureCapacity() {
if (elements.length == size)
elements = java.util.Arrays.copyOf(elements, 2 * size + 1);
}
}
์คํ์ ์์๋ก ๋ณด๋ฉด ์ด ์ฝ๋์์๋ ์คํ์ด ์ปค์ก๋ค๊ฐ ์ค์ด๋ค์์ ๋ ์คํ์์ ๊บผ๋ด์ง ๊ฐ์ฒด๋ค์ ๊ฐ๋น์ง ์ปฌ๋ ํฐ๊ฐ ํ์ํ์ง ์๋๋ค.
ํ๋ก๊ทธ๋จ์์ ๊ทธ ๊ฐ์ฒด๋ค์ ๋ ์ด์ ์ฌ์ฉํ์ง ์๋๋ผ๋ ๋ง์ด๋ค. ์ด ์คํ์ด ๊ทธ ๊ฐ์ฒด๋ค์ ๋ค ์ด ์ฐธ์กฐ(obsolete reference)๋ฅผ ์ฌ์ ํ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ฌ๊ธฐ์ ๋ค ์ด ์ฐธ์กฐ๋. ๋ฌธ์ ๊ทธ๋๋ก ์์ผ๋ก ๋ค์ ์ฐ์ง ์์ ์ฐธ์กฐ๋ฅผ ๋ปํ๋ค.
์์ ์ฝ๋์์๋ elements ๋ฐฐ์ด์ 'ํ์ฑ ์์ญ' ๋ฐ์ ์ฐธ์กฐ๋ค์ด ๋ชจ๋ ์ฌ๊ธฐ์ ํด๋นํ๋ค. ํ์ฑ ์์ญ์ ์ธ๋ฑ์ค๊ฐ size๋ณด๋ค ์์ ์์๋ค๋ก ๊ตฌ์ฑ๋๋ค.
ํด๋ฒ์ ๊ฐ๋จํ๋ค. ํด๋น ์ฐธ์กฐ๋ฅผ ๋ค ์ผ์ ๋ Null ์ฒ๋ฆฌ(์ฐธ์กฐ ํด์ )ํ๋ฉด ๋๋ค.
์์ ์ฝ๋์์๋ ์์์ ์ฐธ์กฐ๊ฐ ๋ ์ด์ ํ์ ์์ด์ง๋ ์์ ์ ์คํ์์ ๊บผ๋ด์ง๋ pop() ๋ฉ์๋์์ ์ด๋ค.
๋ค์๊ณผ ๊ฐ์ด null๋ก ์ฐธ์กฐํด์ ํ๋ฉด ๋๋ค.
if(size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // ๋ค ์ด ์ฐธ์กฐ ํด์
return result;
}
ํ์ง๋ง ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ null ์ฒ๋ฆฌํ๋ ์ผ์ ์์ธ์ ์ธ ๊ฒฝ์ฐ์ฌ์ผ ํ๋ค. ๋ค ์ด ์ฐธ์กฐ๋ฅผ ํด์ ํ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ๊ทธ ์ฐธ์กฐ๋ฅผ ๋ด์ ๋ณ์๋ฅผ ์ ํจ ๋ฒ์(scope) ๋ฐ์ผ๋ก ๋ฐ์ด๋ด๋ ๊ฒ์ด๋ค. ๋ณ์์ ๋ฒ์๋ฅผ ์ต์๊ฐ ๋๊ฒ ์ ์ํ๋ค๋ฉด(์์ดํ 57) ์ด ์ผ์ ์์ฐ์ค๋ฝ๊ฒ ์ด๋ค์ง๋ค.
๊ทธ๋ ๋ค๋ฉด null ์ฒ๋ฆฌ๋ ์ธ์ ํด์ผ ํ ๊น? Stack ํด๋์ค๋ ์ ๋ฉ๋ชจ๋ฆฌ ๋์์ ์ทจ์ฝํ ๊ฑธ๊น?
๋ฐ๋ก ์คํ์ด ์๊ธฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ง์ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ด ์คํ์ elements ๋ฐฐ์ด๋ก ์ ์ฅ์ ํ์ ๋ง๋ค์ด ์์๋ค์ ๊ด๋ฆฌํ๋ค. ๋ฐฐ์ด์ ํ์ฑ ์์ญ์ ์ํ ์์๋ค์ด ์ฌ์ฉ๋๊ณ ๋นํ์ฑ ์์ญ์ ์ฐ์ด์ง ์๋๋ค. ๋ฌธ์ ๋ GC๋ ์ด ์ฌ์ค์ ์ ๊ธธ์ด ์๋ค๋ ๋ฐ ์๋ค. GC๊ฐ ๋ณด๊ธฐ์๋ ๋นํ์ฑ ์์ญ์์ ์ฐธ์กฐํ๋ ๊ฐ์ฒด๋ ๋๊ฐ์ด ์ ํจํ ๊ฐ์ฒด๋ค. ๊ทธ๋ฌ๋ฏ๋ก ํ๋ก๊ทธ๋๋จธ๋ ๋นํ์ฑ ์์ญ์ด ๋๋ ์๊ฐ null ์ฒ๋ฆฌํด์ ํด๋น ๊ฐ์ฒด๋ฅผ ๋๋ ์ฐ์ง ์์ ๊ฒ์์ GC์ ์๋ ค์ผ ํ๋ค.
์ผ๋ฐ์ ์ผ๋ก ์๊ธฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ง์ ๊ด๋ฆฌํ๋ ํด๋์ค๋ผ๋ฉด ํ๋ก๊ทธ๋๋จธ๋ ํญ์ ๋ฉ๋ชจ๋ฆฌ ๋์์ ์ฃผ์ํด์ผ ํ๋ค. ์์๋ฅผ ๋ค ์ฌ์ฉํ ์ฆ์ ์์๊ฐ ์ฐธ์กฐํ ๊ฐ์ฒด๋ค์ ๋ค null ์ฒ๋ฆฌํด์ค์ผ ํ๋ค.
์บ์ ์ญ์ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ์ผ์ผํค๋ ์ฃผ๋ฒ์ด๋ค. ์ด ์ข๊ฒ ์บ์ ์ธ๋ถ์์ ํค(key)๋ฅผ ์ฐธ์กฐํ๋ ๋์๋ง ์ํธ๋ฆฌ๊ฐ ์ด์ ์๋ ์บ์๊ฐ ํ์ํ ์ํฉ์ด๋ผ๋ฉด WeakHashMap์ ์ฌ์ฉํด ์บ์๋ฅผ ๋ง๋ค์. ๋ค ์ด ์ํธ๋ฆฌ๋ ๊ทธ ์ฆ์ ์๋์ผ๋ก ์ ๊ฑฐ๋ ๊ฒ์ด๋ค.
๋จ, WeakHashMap์ ์ด๋ฌํ ์ํฉ์์๋ง ์ ์ฉํ๋ค๋ ๊ฒ์ ๊ธฐ์ตํด์ผ ํ๋ค.
์บ์๋ฅผ ๋ง๋ค ๋ ๋ณดํต์ ์บ์ ์ํธ๋ฆฌ์ ์ ํจ ๊ธฐ๊ฐ์ ์ ํํ ์ ์ํ๊ธฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์ ์๊ฐ์ด ์ง๋ ์๋ก ์ํธ๋ฆฌ์ ๊ฐ์น๋ฅผ ๋จ์ด๋จ๋ฆฌ๋ ๋ฐฉ์์ ํํ ์ฌ์ฉํ๋ค. ์ด๋ฐ ๋ฐฉ์์์๋ ์ฐ์ง ์๋ ์ํธ๋ฆฌ๋ฅผ ์ด๋ฐ๊ธ ์ฒญ์ํด์ค์ผ ํ๋ค. (Scheduled ThreadPoolExecutor ๊ฐ์) ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋๋ฅผ ํ ์ํ๊ฑฐ๋ ์บ์์ ์ ์ํธ๋ฆฌ๋ฅผ ์ถ๊ฐํ ๋ ๋ถ์ ์์ ์ผ๋ก ์ํํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
LinkedHashMap์ removeEldestEntry ๋ฉ์๋๋ฅผ ์จ์ ํ์์ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ๋ค. ๋ ๋ณต์กํ ์บ์๋ฅผ ๋ง๋ค๊ณ ์ถ๋ค๋ฉด java.lang.ref ํจํค์ง๋ฅผ ์ง์ ํ์ฉํด์ผ ํ ๊ฒ์ด๋ค.
๋ฉ๋ชจ๋ฆฌ ๋์์ ์ธ ๋ฒ์งธ ์ฃผ๋ฒ์ ๋ฐ๋ก ๋ฆฌ์ค๋ ํน์ ์ฝ๋ฐฑ์ด๋ผ ๋ถ๋ฅด๋ ๊ฒ์ด๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ์ฝ๋ฐฑ์ ๋ฑ๋ก๋ง ํ๊ณ ๋ช ํํ ํด์น ํ์ง ์๋๋ค๋ฉด, ๋ญ๊ฐ ์กฐ์นํด์ฃผ์ง ์๋ ํ ์ฝ๋ฐฑ์ ๊ณ์ ์์ฌ๊ฐ ๊ฒ์ด๋ค. ์ด๋ด ๋ ์ฝ๋ฐฑ์ ์ฝํ ์ฐธ์กฐ(weak reference)๋ก ์ ์ฅํ๋ฉด ๊ฐ๋น์ง ์ปฌ๋ ํฐ๊ฐ ์ฆ์ ์๊ฑฐํด ๊ฐ๋ค. ์๋ก WeakHashMap์ ํฌ๋ก ์ ์ฅํ๋ฉด ๋๋ค.
ํต์ฌ ์ ๋ฆฌ
๋ฉ๋ชจ๋ฆฌ ๋์๋ ๊ฒ์ผ๋ก ์ ๋๋ฌ๋์ง ์์ ์์คํ ์ ์๋ ๊ฐ ์ ๋ณตํ๋ ์ฌ๋ก๋ ์๋ค. ์ด๋ฐ ๋์๋ ์ฒ ์ ํ ์ฝ๋ ๋ฆฌ๋ทฐ๋ ํ ํ๋กํ์ผ๋ฌ ๊ฐ์ ๋๋ฒ๊น ๋๊ตฌ๋ฅผ ๋์ํด์ผ๋ง ๋ฐ๊ฒฌ๋๊ธฐ๋ ํ๋ค. ๊ทธ๋์ผ ์ด๋ฐ ์ข ๋ฅ์ ๋ฌธ์ ๋ ์๋ฐฉ๋ฒ์ ์ตํ๋๋ ๊ฒ์ด ๋งค์ฐ ์ค์ํ๋ค.
. ์์ดํ 8 - finalizer์ cleaner ์ฌ์ฉ์ ํผํ๋ผ
์๋ฐ๋ ๋ ๊ฐ์ง ๊ฐ์ฒด ์๋ฉธ์๋ฅผ ์ ๊ณตํ๋ค. ๊ทธ์ค finalizer๋ ์์ธกํ ์ ์๊ณ , ์ํฉ์ ๋ฐ๋ผ ์ํํ ์ ์์ด ์ผ๋ฐ์ ์ผ๋ก ๋ถํ์ํ๋ค. ์ค๋์, ๋ฎ์ ์ฑ๋ฅ ์ด์์ฑ ๋ฌธ์ ์ ์์ธ์ด ๋๊ธฐ๋ ํ๋ค. ์ด๋ฒ ์ฅ์์ ๋ช ๊ฐ์ง ์ฐ์์๋ฅผ ์๊ฐํ์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก '์ฐ์ง ๋ง์์ผ' ํ๋ค. ๊ทธ๋์ ์๋ฐ 9์์๋ finalizer๋ฅผ ์ฌ์ฉ ์์ (deprecated) API๋ก ์ง์ ํ๊ณ cleaner๋ฅผ ๊ทธ ๋์์ผ๋ก ์๊ฐํ๋ค.
cleaner๋ finalizer๋ณด๋ค๋ ๋ ์ํํ์ง๋ง, ์ฌ์ ํ ์์ธกํ ์ ์๊ณ , ๋๋ฆฌ๊ณ , ์ผ๋ฐ์ ์ผ๋ก ๋ถ ํ์ํ๋ค.
finalizer์ cleaner๋ ์ฆ์ ์ํ๋๋ค๋ ๋ณด์ฅ์ด ์๋ค. ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์๊ฒ ๋ ํ finalizer๋ cleaner๊ฐ ์คํ๋๊ธฐ๊น์ง ์ผ๋ง๋ ๊ฑธ๋ฆด์ง ์ ์ ์๋ค. ์ฆ, finalizer์ cleaner๋ก๋ ์ ๋ ์คํ๋์ด์ผ ํ๋ ์์ ์ ์ ๋ ํ ์ ์๋ค.
์์ปจ๋ ํ์ผ ๋ซ๊ธฐ๋ฅผ finalizer๋ cleaner์ ๋งก๊ธฐ๋ฉด ์ค๋ํ ์ค๋ฅ๋ฅผ ์ผ์ผํฌ ์ ์๋ค. ์์คํ ์ด ๋์์ ์ด ์ ์๋ ํ์ผ ๊ฐ์์ ํ๊ณ๊ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค.
finalizer์ cleaner๋ฅผ ์ผ๋ง๋ ์ ์ํ ์ํํ ์ง๋ ์ ์ ์ผ๋ก ๊ฐ๋น์ง ์ปฌ๋ ํฐ ์๊ณ ๋ฆฌ์ฆ์ ๋ฌ๋ ค์๋ค.
์๋ฐ ์ธ์ด ๋ช ์ธ๋ finalizer ๋ cleaner์ ์ํ ์์ ๋ฟ ์๋๋ผ ์ํ ์ฌ๋ถ์กฐ์ฐจ ๋ณด์ฅํ์ง ์๋๋ค.
์ ๊ทผํ ์ ์๋ ์ผ๋ถ ๊ฐ์ฒด์ ๋ธ๋ฆฐ ์ข ๋ฃ ์์ ์ ์ ํ ์ํํ์ง ๋ชปํ ์ฑ ํ๋ก๊ทธ๋จ์ด ์ค๋จ๋ ์๋ ์๋ค๋ ์๊ธฐ๋ค ๋ฐ๋ผ์ ํ๋ก๊ทธ๋จ ์์ ์ฃผ๊ธฐ์ ์๊ด์๋, ์ํ๋ฅผ ์๊ตฌ์ ์ผ๋ก ์์ ํ๋ ์์ ์์๋ ์ ๋ finlizer๋ cleaner์ ์์กดํด์๋ ์ ๋๋ค.
์๋ก DB ๊ฐ์ ๊ณต์ ์์์ ์๊ตฌ ๋ฝ ํด์ ๋ฅผ finalizer๋ cleaner์ ๋งก๊ฒจ ๋์ผ๋ฉด ๋ถ์ฐ ์์คํ ์ ์ฒด๊ฐ ์์ํ ๋ฉ์ถ๊ฒ ๋ ๊ฒ์ด๋ค.
finalizer๋ ์ฌ์ฉํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ํ๊ดดํ๋ GC์ ํจ์จ์ ๋จ์ด๋จ๋ฆฐ๋ค.
finalizer๋ฅผ ์ฌ์ฉํ ํด๋์ค๋ finalizer ๊ณต๊ฒฉ์ ๋ ธ์ถ๋์ด ์ฌ๊ฐํ ๋ณด์ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์๋ค. ๊ณต๊ฒฉ ์๋ฆฌ๋ ์์ฑ์๋ ์ง๋ ฌํ ๊ณผ์ ์์ ์์ธ๊ฐ ๋ฐ์ํ๋ฉด, ์ด ์์ฑ๋๋ค ๋ง ๊ฐ์ฒด์์ ์ ์์ ์ธ ํ์ ํด๋์ค์ finalizer๊ฐ ์ํ๋ ์ ์๊ฒ ๋๋ค. ๊ฐ์ฒด์ ์์ฑ์ ๋ง์ผ๋ ค๋ฉด ์์ฑ์์์ ์์ธ๋ฅผ ๋์ง๋ ๊ฒ๋ง์ผ๋ก ์ถฉ๋ถํ์ง๋ง, finalizer๊ฐ ์๋ค๋ฉด ๊ทธ๋ ์ง๋ ์๋ค.
final์ด ์๋ ํด๋์ค๋ฅผ finalizer ๊ณต๊ฒฉ์ผ๋ก๋ถํฐ ๋ฐฉ์ดํ๋ ค๋ฉด ์๋ฌด ์ผ๋ ํ์ง ์๋ finalize ๋ฉ์๋๋ฅผ ๋ง๋ค๊ณ final๋ก ์ ์ธํด ํ์ ํด๋์ค๋ฅผ ๋ง๋ค ์ ์๊ฒ ํ์.
finalizer๋ cleaner ๋์์ผ๋ก๋ AutoCloseable์ ๊ตฌํํด ์ฃผ๊ณ , ํด๋ผ์ด์ธํธ์์ ์ธ์คํด์ค๋ฅผ ๋ค ์ฐ๊ณ ๋๋ฉด close ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ๋๋ค. (์์ดํ 9 ์ฐธ์กฐ).
finalizer์ cleaner์ ์ฐ์์๋ ์ด๋์ผ๊น?
1. ์์์ ์์ ์๊ฐ close ๋ฉ์๋๋ฅผ ํธ์ถํ์ง ์์ ๊ฒ์ ๋ํ ์์ ๋ง ์ญํ .
- finalizer์ cleaner๊ฐ ์ฆ์ ํธ์ถ ๋๋ฆฌ๋ผ๋ ๋ณด์ฅ์ ์์ง๋ง, ํด๋ผ์ด์ธํธ๊ฐ ํ์ง ์์ ์์ ํ์๋ฅผ ๋ฆ๊ฒ๋๋ง ํด์ฃผ๋ ๊ฒ์ด ์์ ํ์ง ์๋ ๊ฒ๋ณด๋ค ๋ซ๋ค.
2. ๋ค์ดํฐ๋ธ ํผ์ด ์ฐ๊ฒฐ ๊ฐ์ฒด ํ์
- ๋ค์ดํฐ๋ธ ํผ์ด(Native peer)๋ ์ผ๋ฐ ์๋ฐ ๊ฐ์ฒด๊ฐ ๋ค์ดํฐ๋ธ ๋ฉ์๋๋ฅผ ํตํด ๊ธฐ๋ฅ์ ์์ํ ๋ค์ดํฐ๋ธ ๊ฐ์ฒด๋ฅผ ๋งํ๋ค. ๋ค์ดํฐ๋ธ ํผ์ด๋ ์๋ฐ ๊ฐ์ฒด๊ฐ ์๋๋ GC๋ ๊ทธ ์กด์ฌ๋ฅผ ์์ง ๋ชปํ๋ค. ๋ฐ๋ผ์ finalizer๋ cleaner ๊ฐ ์ฒ๋ฆฌํ๊ธฐ์ ์ ๋นํ ์์ ์ด๋ค.
๋จ, ์ฑ๋ฅ ์ ํ๋ฅผ ๊ฐ๋นํ ์ ์๊ฑฐ๋, ๋ค์ดํฐ๋ธ ํผ์ด๊ฐ ์ฌ์ฉํ๋ ์์์ ์ฆ์ ํ์ ํด์ผ ํ๋ค๋ฉด close๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
cleaner ์ฌ์ฉ ์
Room ํด๋์ค๋ก ๋ฐฉ(room) ์์์ ์๊ฑฐํ๊ธฐ ์ ์ ๋ฐ๋์ ์ฒญ์(clean) ํด์ผ ํ๋ค.
public class Room implements AutoCloseable {
private static final Cleaner cleaner = Cleaner.create();
// ์ฒญ์๊ฐ ํ์ํ ์์. ์ ๋ Room์ ์ฐธ์กฐํด์๋ ์ ๋๋ค!
private static class State implements Runnable{
int numJunkPiles; // Room ์์ ์ฐ๋ ๊ธฐ ์
State(int numJunkPiles){
this.numJunkPiles = numJunkPiles;
}
// close ๋ฉ์๋๋ cleaner๊ฐ ํธ์ถํ๋ค.
@Override
public void run() {
System.out.println("Cleaning Room");
numJunkPiles = 0;
}
}
private final State state;
private final Cleaner.Cleanable cleanable;
public Room(int numJunkPiles){
state = new State(numJunkPiles);
cleanable = cleaner.register(this, state);
}
@Override
public void close() throws Exception {
cleanable.clean();
}
}
run() ๋ฉ์๋๊ฐ ํธ์ถ๋๋ ์ํฉ์ ๋ ์ค ํ๋์ด๋ค.
๋ณดํต์ Room์ close ๋ฉ์๋๋ฅผ ํธ์ถํ ๋๋ค. close ๋ฉ์๋์์ Cleanable์ clean์ ํธ์ถํ๋ฉด ์ด ๋ฉ์๋ ์์์ run์ ํธ์ถํ๋ค.
ํน์ GC๊ฐ Room์ ํ์ํ ๋๊น์ง ํด๋ผ์ด์ธํธ๊ฐ close๋ฅผ ํธ์ถํ์ง ์๋๋ค๋ฉด, cleaner๊ฐ State์ run ๋ฉ์๋๋ฅผ ํธ์ถํด ์ค ๊ฒ์ด๋ค.
State ์ธ์คํด์ค๋ '์ ๋๋ก' Room ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํด์๋ ์ ๋๋ค.
Room ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ ๊ฒฝ์ฐ ์ํ์ฐธ์กฐ๊ฐ ์๊ฒจ GC๊ฐ Room ์ธ์คํด์๋ฅผ ํ์ ํด๊ฐ ๊ธฐํ๊ฐ ์ค์ง ์๋๋ค.
State๊ฐ ์ ์ ์ค์ฒฉ ํด๋์ค์ธ ์ด์ ๊ฐ ์๋ค. ์ ์ ์ด์๋ ์ค์ฒฉ ํด๋์ค๋ ์๋์ผ๋ก ๋ฐ๊นฅ ๊ฐ์ฒด์ ์ฐธ์กฐ๋ฅผ ๊ฐ๊ฒ ๋๊ธฐ ๋๋ฌธ์ด๋ค(์์ดํ 24)
์์ ์ด์ผ๊ธฐํ ๋๋ก Room์ cleaner๋ ๋จ์ง ์์ ๋ง์ด๋ค. ํด๋ผ์ด์ธํธ๊ฐ ๋ชจ๋ Room ์์ฑ์ try-with-resources ๋ธ๋ก์ผ๋ก ๊ฐ์๋ค๋ฉด ์๋ ์ฒญ์๋ ์ ํ ํ์ํ์ง ์๋ค.
์ข์ ์
// try-with-resources๋ฅผ ์ฌ์ฉํด ์์ธ๋ฅผ ํํผํ๋ค.
try(Room room = new Room(7)){
System.out.println("์๋ ");
}
}
์ข์ง ์์ ์
// try-with-resources๋ฅผ ์ฌ์ฉํ์ง ์์ ๋ฐฉ์ฒญ์๋ฅผ ์ถ๋ ฅ๋๋ฆฌ๋ผ ๊ธฐ๋ํ ์ ์๋ค.
// Room ์์ฑ์์์ Cleaner์ register ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด์ Room์ ์ฐธ์กฐํ๋ฏ๋ก Room์ Cleaner๊ฐ ์๊ฑฐํ ๋๊น์ง ํ์๋์ง ์๋๋ค.
// ๋ฐ๋ผ์ Room์ close ๋ฉ์๋๋ ํธ์ถ๋์ง ์๊ณ , Room์ ๋ด๊ธด ์ฐ๋ ๊ธฐ ์๋ 0์ผ๋ก ์ด๊ธฐํ๋์ง ์๋๋ค.
// ์ด ํ๋ก๊ทธ๋จ์ "Peace out"์ ์ถ๋ ฅํ๊ณ ์ข ๋ฃ๋๋ค.
// ์ด๋ฐ ์ํฉ์ ๋ฐฉ์งํ๋ ค๋ฉด Room์ try-with-resources ๋ธ๋ก ๋ฐ๊นฅ์์ ์ด๊ธฐํํด์ผ ํ๋ค.
// try-with-resources ๋ธ๋ก ๋ฐ๊นฅ์์ ์ด๊ธฐํํ๋ฉด Room์ด ์์ํ ์ด๋ ค์์ง ์๊ฒ ๋๋ค.
Room room = new Room(99);
System.out.println("Peace out");
}
- System.exit์ ํธ์ถํ ๋์ cleaner ๋์์ ๊ตฌํํ๊ธฐ ๋๋ฆ์ด๋ค. ์ฒญ์๊ฐ ์ด๋ค์ง์ง๋ ๋ณด์ฅํ์ง ์๋๋ค.
ํต์ฌ ์ ๋ฆฌ
cleaner(์๋ฐ 8๊น์ง๋ finalizer)๋ ์์ ๋ง ์ญํ ์ด๋ ์ค์ํ์ง ์์ ๋ค์ดํฐ๋ธ ์์ ํ์์ฉ์ผ๋ก๋ง ์ฌ์ฉํ์. ๋ฌผ๋ก ์ด๋ฐ ๊ฒฝ์ฐ๋ผ๋ ๋ถํ์ค์ฑ๊ณผ ์ฑ๋ฅ ์ ํ์ ์ฃผ์ํด์ผ ํ๋ค.
.์์ดํ 9 - try-finally ๋ณด๋ค๋ try-with-resources๋ฅผ ์ฌ์ฉํ๋ผ.
java ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ close ๋ฉ์๋๋ฅผ ํธ์ถํด ์ง์ ๋ซ์์ค์ผ ํ๋ ์์์ด ๋ง๋ค. Stream, Connection ๋ฑ์ด ์๋ค.
์ ํต์ ์ผ๋ก ์์์ด ์ ๋๋ก ๋ซํ์ ๋ณด์ฅํ๋ ์๋จ์ธ try-finally
BufferedReader br = new BufferedReader(new java.io.FileReader(path));
try {
return br.readLine();
} finally {
br.close();
}
}
์์์ ํ๋ ๋ ์ผ์ ๊ฒฝ์ฐ?
InputStream in = new FileInputStream(src);
try {
OutputStream out = new FileOutputStream(dst);
try {
byte[] buf = new byte[100];
int n;
while((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
} finally {
out.close();
}
} finally {
in.close();
}
}
try-finally ๋ฌธ์ ์ ๋๋ก ์ฌ์ฉํ ์์ ๋ ์ฝ๋ ์์ ์์กฐ์ฐจ ๋ฏธ๋ฌํ ๊ฒฐ์ ์ด ์๋ค.
์์ธ๋ tryh ๋ธ๋ก๊ณผ finally ๋ธ๋ก ๋ชจ๋์์ ๋ฐ์ํ ์ ์๋ค. ์๋ก ๊ธฐ๊ธฐ์ ๋ฌผ๋ฆฌ์ ๋ฌธ์ ๊ฐ ์๊ธธ ๊ฒฝ์ฐ firstLineOfFile ๋ฉ์๋ ์์ readLine ๋ฉ์๋๊ฐ ์์ธ๋ฅผ ๋์ง๊ณ , ๊ฐ์ ์ด์ ๋ก close ๋ฉ์๋๋ ์คํจํ ๊ฒ์ด๋ค. ์ด๋ฐ ์ํฉ์ด๋ผ๋ฉด ๋ ๋ฒ์งธ ์์ธ๊ฐ ์ฒซ ๋ฒ์งธ ์์ธ๋ฅผ ์์ ํ ์ง์ด์ผํค๊ฒ ๋๋ค. ์ด๋ก์ธ ํค ์ค์ ์ค๋ฅ ํ์ ์ด ํ๋ค๊ฒ ๋๊ณ ๋๋ฒ๊น ์ ๋ชน์ ์ด๋ ต๊ฒ ํ๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ค์ ์๋ฐ 7์์ try-with-resources ๋์ ๋ชจ๋ ํด๊ฒฐ๋์๋ค.
์ด ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ํด๋น ์์์ด AutoCloseable ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผ ํ๋ค. ๋จ์ํ void๋ฅผ ๋ฐํํ๋ close ๋ฉ์๋ ํ๋๋ง ๋ฉ๊ทธ๋ฌ๋ ์ ์ํ ์ธํฐํ์ด์ค๋ค. ์๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ์๋ง์ ํด๋์ค์ ์ธํฐํ์ด์ค๊ฐ ์ด๋ฏธ AutoCloseable์ ๊ตฌํํ๊ฑฐ๋ ํ์ฅํด ๋๋ค. ๋ง์ผ ๋ซ์์ผ ํ๋ ์์์ ๋ปํ๋ ํด๋์ค๋ฅผ ์์ฑํ๋ค๋ฉด AutoCloseable์ ๋ฐ๋์ ๊ตฌํํ๊ธฐ ๋ฐ๋๋ค.
์์ ๋ ๋ฉ์๋๋ฅผ try-with-resources๋ฅผ ์ ์ฉํ ๋ชจ์ต์ด๋ค.
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
static void copy(String src, String dst) throws Exception {
try (InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst)) {
byte[] buf = new byte[100];
int n;
while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
}
}
์์ ๋ฒ์ ์ด ์ฝ๊ธฐ ์์ํ ๋ฟ ์๋๋ผ. ๋ฌธ์ ์ง๋จ์๋ ํจ์ฌ ์ข๋ค.
readLine๊ณผ close ํธ์ถ ์์ชฝ์์ ์์ธ ๋ฐ์ํ๊ฒ ๋ ๊ฒฝ์ฐ, close์์ ๋ฐ์ํ ์์ธ๋ ์จ๊ฒจ์ง๊ณ readLine์์ ๋ฐ์ํ ์์ธ๊ฐ ๊ธฐ๋ก๋๋ค. ์ด๋ ๊ฒ ์จ๊ฒจ์ง ์์ธ๋ค๋ ๊ทธ๋ฅ ๋ฒ๋ ค์ง์ง๋ ์๊ณ , ์คํ ์ถ์ ๋ด์ญ์ '์จ๊ฒจ์ก๋ค(suppressed)'๋ผ๋ ๊ผฌ๋ฆฌํ๋ฅผ ๋ฌ๊ณ ์ถ๋ ฅ๋๋ค. ๋ํ Java 7์์ Throwable์ ์ถ๊ฐ๋๋ getSuppressed ๋ฉ์๋๋ฅผ ์ด์ฉํ๋ฉด ํ๋ก๊ทธ๋จ ์ฝ๋์์ ๊ฐ์ ธ์ฌ ์๋ ์๋ค.
๋ณดํต์ try-finally์ฒ๋ผ try-with-resoureces์์๋ catch ์ ์ด ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
} catch (IOException e) {
return "Error";
}
}
ํต์ฌ ์ ๋ฆฌ
๊ผญ ํ์ํด์ผ ํ๋ ์์์ ๋ค๋ฃฐ ๋๋ try-finally ๋ง๊ณ , try-with-resources๋ฅผ ์ฌ์ฉํ์.
์์ธ๋ ์๋ค. ์ฝ๋๋ ๋ ์งง๊ณ ๋ถ๋ช ํด์ง๊ณ , ๋ง๋ค์ด์ง๋ ์์ธ ์ ๋ณด๋ ํจ์ฌ ์ ์ฉํ๋ค. try-finally๋ก ์์ฑํ๋ฉด ์ค์ฉ์ ์ด์ง ๋ชปํ ๋งํผ ์ฝ๋๊ฐ ์ง์ ๋ถํด์ง๋ ๊ฒฝ์ฐ๋ผ๋, try-with-resources๋ก๋ ์ ํํ๊ณ ์ฝ๊ฒ ์์์ ํ์ํ ์ ์๋ค.
Gihub Code - https://github.com/younwony/effectiveJava/tree/master/src/main/java/dev/wony/effectivejava/chapter_1
๐ ๋๋์ .
์๊ฐ๋ณด๋ค ๋ชฐ๋๋ ๋ถ๋ถ๋ค์ด ๋ง์์ ๋ถ์กฑํ ๋ถ๋ถ์ ๋ง์ด ์ฑ์ด ๋๋์ด์๋ค.
'Study > Effective Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Effective Java 3/E] 4์ฅ ํด๋์ค์ ์ธํฐํ์ด์ค (0) | 2023.05.23 |
---|---|
[Effective Java 3/E] 3์ฅ ๋ชจ๋ ๊ฐ์ฒด์ ๊ณตํต ๋ฉ์๋ (1) | 2023.05.07 |
[Effective Java 3/E] 1์ฅ ๋ค์ด๊ฐ๊ธฐ (0) | 2023.04.18 |