item 26 junghyunlyoo - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
ํด๋์ค์ ์ธํฐํ์ด์ค ์ ์ธ์ ํ์ ๋งค๊ฐ๋ณ์๊ฐ ์ฐ์ด๋ฉด ์ด๋ฅผ ์ ๋ค๋ฆญ ํด๋์ค ํน์ ์ ๋ค๋ฆญ ์ธํฐํ์ด์ค๋ผ ํ๋ค.
์๋ฅผ ๋ค์ด, List ์ธํฐํ์ด์ค๋ ์์์ ํ์ ์ ๋ํ๋ด๋ ํ์ ๋งค๊ฐ๋ณ์ E๋ฅผ ๋ฐ๋๋ค.
์ด List ์ธํฐํ์ด์ค์ ์์ ํ ์ด๋ฆ์ List์ด๋ค. ํ์ง๋ง ์งง๊ฒ List ๋ผ๊ณ ๋ ์์ฃผ ์ด๋ค.
์ ๋ค๋ฆญ ํด๋์ค์ ์ ๋ค๋ฆญ ์ธํฐํ์ด์ค๋ฅผ ํตํ์ด ์ ๋ค๋ฆญ ํ์ (generic type)์ด๋ผ ํ๋ค.
๊ฐ๊ฐ์ ์ ๋ค๋ฆญ ํ์ ์ ์ผ๋ จ์ ๋งค๊ฐ๋ณ์ํ ํ์ ์ ์ ์ํ๋ค.
๋จผ์ ํด๋์ค๋ ์ธํฐํ์ด์ค ์ด๋ฆ์ด ๋์ค๊ณ ์ด์ด์ ๊บพ์ ๊ดํธ ์์ ์ค์ ํ์ ๋งค๊ฐ๋ณ์๋ค์ ๋์ดํ๋ค.
์๋ฅผ ๋ค์ด List์ ์์์ ํ์ ์ด String์ธ ๋ฆฌ์คํธ๋ฅผ ๋ปํ๋ ๋งค๊ฐ๋ณ์ํ ํ์ ์ด๋ค.
์ฌ๊ธฐ์ String์ด ์ ๊ท ํ์ ๋งค๊ฐ๋ณ์ E์ ํด๋นํ๋ ์ค์ ํ์ ๋งค๊ฐ๋ณ์๋ค.
์ ๋ค๋ฆญ ํ์ ์ ํ๋ ์ ์ํ๋ฉด ๊ทธ์ ๋ธ๋ฆฐ ๋ก ํ์ ๋ ํจ๊ป ์ ์๋๋ค.
๋ก ํ์ ์ด๋ ์ ๋ค๋ฆญ ํ์ ์์ ํ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ํ ์ฌ์ฉํ์ง ์์ ๋๋ฅผ ๋งํ๋ค.
์์ปจ๋ List์ ๋ก ํ์ ์ List๋ค.
๋ก ํ์ ์ ํ์ ์ ์ธ์์ ์ ๋ค๋ฆญ ํ์ ์ ๋ณด๊ฐ ์ ๋ถ ์ง์์ง ๊ฒ์ฒ๋ผ ๋์ํ๋ค.
์ด๋ ์ ๋ค๋ฆญ์ด ๋๋ํ๊ธฐ ์ ์ ์ฝ๋์ ํธํ๋๋๋ก ํ๊ธฐ ์ํ ๊ถ์ฌ์ง์ฑ ์ด๋ค.
์ ๋ค๋ฆญ์ ์ง์ํ๊ธฐ ์ ์๋ ์ปฌ๋ ์ ์ ๋ค์๊ณผ ๊ฐ์ด ์ ์ธํ๋ค.
์๋ฐ 9์์๋ ์ฌ์ ํ ๋์ํ์ง๋ง ์ข์ ์๋ผ๊ณ ๋ณผ ์ ์๋ค.
private final Collection stamps = ...;
์ด ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ค์๋ก ๋์ฅ(stamp) ๋์ ๋์ (Coin)์ ๋ฃ์ด๋ ์๋ฌด ์ค๋ฅ์์ด ์ปดํ์ผ๋๊ณ ์คํ๋๋ค.
(์ปดํ์ผ๋ฌ๊ฐ ๋ชจํธํ ๊ฒฝ๊ณ ๋ฉ์ธ์ง๋ฅผ ๋ณด์ฌ์ฃผ๊ธด ํ ๊ฒ์ด๋ค)
stamps.add(new Coin());
์ด ๋์ ์ ์ปฌ๋ ์ ์์ ๋ค์ ๊บผ๋ด๊ธฐ ์ ์๋ ์ค๋ฅ๋ฅผ ์ ์ ์๋ค.
for (Iterator i = stamps.iterator(); i.hasNext(); ) {
Stamp stamp = (Stamp) i.next(); //ClassCastException
}
์ค๋ฅ๋ ๊ฐ๋ฅํ ํ ๋ฐ์ ์ฆ์, ์ด์์ ์ผ๋ก๋ ์ปดํ์ผํ ๋ ๋ฐ๊ฒฌํ๋ ๊ฒ์ด ์ข๋ค.
์ด ์์์๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ณ ํ์ฐธ ๋ค์ธ ๋ฐํ์์์ผ ์์์ฑ ์ ์๋ค.
์ด๋ ๊ฒ ๋๋ฉด ๋ฐํ์์ ๋ฌธ์ ๋ฅผ ๊ฒช๋ ์ฝ๋์ ์์ธ์ ์ ๊ณตํ ์ฝ๋๊ฐ ๋ฌผ๋ฆฌ์ ์ผ๋ก ์๋นํ ๋จ์ด์ ธ ์์ ๊ฐ๋ฅ์ฑ์ด ์ปค์ง๋ค.
ClassCastException์ด ๋ฐ์ํ๋ฉด stamps์ ๋์ ์ ๋ฃ์ ์ง์ ์ ์ฐพ๊ธฐ ์ํด ์ฝ๋ ์ ์ฒด๋ฅผ ํ์ด๋ด์ผ ํ ์๋ ์๋ค.
์ ๋ค๋ฆญ์ ํ์ฉํ๋ฉด ์ด ์ค๋ฅ๋ฅผ ๋ฐฉ์งํ ์ ์๋ค.
private final Collection<Stamp> stamps = ...;
์ด๋ ๊ฒ ์ ์ธํ๋ฉด ์ปดํ์ผ๋ฌ๋ stamps์๋ Stamp์ ์ธ์คํด์ค๋ง ๋ฃ์ด์ผ ํจ์ ์ปดํ์ผ๋ฌ๊ฐ ์ธ์งํ๊ฒ ๋๋ค.
๋ฐ๋ผ์ ์๋ฌด๋ฐ ๊ฒฝ๊ณ ์์ด ์ปดํ์ผ๋๋ค๋ฉด ์๋๋๋ก ๋์ํ ๊ฒ์์ ๋ณด์ฅํ๋ค.
(๋ฌผ๋ก ์ปดํ์ผ๋ฌ ๊ฒฝ๊ณ ๋ฅผ ์จ๊ธฐ์ง ์์์ด์ผ ํ๋ค. item 27)
stamps์ Stamp ์ด์ธ์ ์ธ์คํด์ค๋ฅผ ๋ฃ์ผ๋ ค ํ๋ฉด ์ปดํ์ผ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉฐ ๋ฌด์์ด ์๋ชป๋๋์ง๋ฅผ ์ ํํ ์๋ ค์ค๋ค.
์ปดํ์ผ๋ฌ๋ ์ปฌ๋ ์ ์์ ์์๋ฅผ ๊บผ๋ด๋ ๋ชจ๋ ๊ณณ์ ๋ณด์ด์ง ์๋ ํ๋ณํ์ ์ถ๊ฐํ์ฌ ์ ๋ ์คํจํ์ง ์์์ ๋ณด์ฅํ๋ค.
Stamp์ฉ ์ปฌ๋ ์ ์ Coin์ ๋ฃ๋๋ค๋ ์๊ฐ ์ต์ง์ค๋ฌ์ ๋ณด์ด๊ฒ ์ง๋ง ํ์ ์์๋ ์ข ์ข ์ผ์ด๋๋ ์ผ์ด๋ค.
(BigDecimal์ฉ ์ปฌ๋ ์ ์ BigInteger๋ฅผ ๋ฃ๋ ๊ฒฝ์ฐ ๋ฑ)
๋กํ์ ์ ์ฐ๋ ๊ฑธ ์ธ์ด ์ฐจ์์์ ๋ง์ ๋์ง๋ ์์์ง๋ง ์ ๋๋ก ์จ์๋ ์ ๋๋ค.
๋ก ํ์ ์ ์ฐ๋ฉด ์ ๋ค๋ฆญ์ด ์๊ฒจ์ฃผ๋ ์์ ์ฑ๊ณผ ํํ๋ ฅ์ ๋ชจ๋ ์๊ฒ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ก ํ์ ์ ์ ์กด์ฌํ๋ ๊ฑธ๊น? ๋ฐ๋ก ํธํ์ฑ ๋๋ฌธ์ด๋ค.
์๋ฐ๊ฐ ์ ๋ค๋ฆญ์ ๋ฐ์๋ค์ด๊ธฐ๊น์ง ๊ฑฐ์ 10๋ ์ด ๊ฑธ๋ ธ๊ธฐ ๋๋ฌธ์ ์ ๋ค๋ฆญ ์์ด ์ง ์ฝ๋๊ฐ ์ด๋ฏธ ๋๋ฆฌ ์ฌ์ฉ๋๊ณ ์๋ค.
๊ทธ๋์ ๊ธฐ์กด ์ฝ๋๋ฅผ ๋ชจ๋ ์์ฉํ๋ฉด์ ์ ๋ค๋ฆญ์ ์ฌ์ฉํ๋ ์๋ก์ด ์ฝ๋์๋ ๋ง๋ฌผ๋ ค ๋์๊ฐ๊ฒ ํด์ผ๋ง ํ๋ค.
๋ก ํ์ ์ ์ฌ์ฉํ๋ ๋ฉ์๋์ ๋งค๊ฐ๋ณ์ํ ํ์ ์ ์ธ์คํด์ค๋ฅผ ๋๊ฒจ๋ (ํน์ ๊ทธ ๋ฐ๋๋) ์ ์์ ์ผ๋ก ๋์ํด์ผ๋ง ํ๋ ๊ฒ์ด๋ค.
์ด ๋ง์ด๊ทธ๋ ์ด์ ํธํ์ฑ์ ์ํด ๋ก ํ์ ์ ์ง์ํ๊ณ ์ ๋ค๋ฆญ ๊ตฌํ์๋ ์๊ฑฐ(erasure; item 28) ๋ฐฉ์์ ์ฌ์ฉํ๊ธฐ๋ก ํ๋ค.
List๊ฐ์ ๋ก ํ์ ์ ์ฌ์ฉํด์๋ ์ ๋๋, List์ฒ๋ผ ์์ ๊ฐ์ฒด๋ฅผ ํ์ฉํ๋ ๋งค๊ฐ๋ณ์ํ ํ์ ์ ๊ด์ฐฎ๋ค.
๋ก ํ์ ์ธ List์ ๋งค๊ฐ๋ณ์ํ ํ์ ์ธ List์ ์ฐจ์ด๋ ๋ฌด์์ผ๊น?
List๋ ์ ๋ค๋ฆญ ํ์ ์์ ์์ ํ ๋ฐ์ ๋บ ๊ฒ์ด๊ณ
List๋ ๋ชจ๋ ํ์ ์ ํ์ฉํ๋ค๋ ์์ฌ๋ฅผ ์ปดํ์ผ๋ฌ์ ๋ช ํํ ์ ๋ฌํ ๊ฒ์ด๋ค.
๋งค๊ฐ๋ณ์๋ก List๋ฅผ ๋ฐ๋ ๋ฉ์๋์ List์ ๋๊ธธ ์ ์์ง๋ง
List๋ฅผ ๋ฐ๋ ๋ฉ์๋์๋ ๋๊ธธ ์ ์๋ค.
์ด๋ ์ ๋ค๋ฆญ์ ํ์ ํ์ ๊ท์น ๋๋ฌธ์ด๋ค.
์ฆ, List์ ๋ก ํ์ ์ธ List์ ํ์ ํ์ ์ด์ง๋ง List์ ํ์ ํ์ ์ ์๋๋ค. (item 28)
๊ทธ ๊ฒฐ๊ณผ, List ๊ฐ์ ๋งค๊ฐ๋ณ์ํ ํ์ ์ ์ฌ์ฉํ ๋์ ๋ฌ๋ฆฌ List ๊ฐ์ ๋ก ํ์ ์ ์ฌ์ฉํ๋ฉด ํ์ ์์ ์ฑ์ ์๊ฒ ๋๋ค.
๋ค์์ ๋ก ํ์ ์ ์ฌ์ฉํ, ๋ฐํ์์ ์คํจํ๋ ์ฝ๋์ด๋ค.
public class Raw {
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
unsafeAdd(strings, Integer.valueOf(42));
String s = strings.get(0); // ์ปดํ์ผ๋ฌ๊ฐ ์๋์ผ๋ก ํ๋ณํ ์ฝ๋๋ฅผ ๋ฃ์ด์ค๋ค.
}
private static void unsafeAdd(List list, Object o) {
list.add(o);
}
}
์ด ์ฝ๋๋ ์ปดํ์ผ์ ๋๋ค. ํ์ง๋ง ๋ก ํ์ ์ธ List๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๊ฒฝ๊ณ ๋ฌธ๊ตฌ๊ฐ ์๊ธด๋ค.
์ด ํ๋ก๊ทธ๋จ์ ์คํํ๋ฉด strings.get(0)์ ๊ฒฐ๊ณผ๋ฅผ ํ๋ณํํ๋ ค ํ ๋ ClassCastException์ ๋์ง๋ค.
Integer๋ฅผ String์ผ๋ก ๋ณํํ๋ ค ์๋ํ ๊ฒ์ด๋ค.
์ด ํ ๋ณํ์ ์ปดํ์ผ๋ฌ๊ฐ ์๋์ผ๋ก ๋ง๋ค์ด์ค ๊ฒ์ด๋ผ ๋ณดํต์ ์คํจํ์ง ์๋๋ค.
ํ์ง๋ง ์ด ๊ฒฝ์ฐ์ ์ปดํ์ผ๋ฌ ๊ฒฝ๊ณ ๋ฅผ ๋ฌด์ํ๊ธฐ ๋๋ฌธ์ ๋ฐํ์์ ์คํจํ๋ค.
๋ก ํ์ ์ธ List๋ฅผ ๋งค๊ฐ๋ณ์ํ ํ์ ์ธ List๋ก ๋ฐ๊พผ ๋ค์ ๋ค์ ์ปดํ์ผํด๋ณด์.
์ค๋ฅ ๋ฉ์ธ์งํ ํจ๊ป ์ปดํ์ผ ์กฐ์ฐจ ๋์ง ์์ ๊ฒ์ด๋ค.
์ ๋ค๋ฆญ ํ์ ์ ์ฐ๊ณ ์ถ์ง๋ง ์ค์ ํ์ ๋งค๊ฐ๋ณ์๊ฐ ๋ฌด์์ธ์ง ์ ๊ฒฝ ์ฐ๊ณ ์ถ์ง ์๋ค๋ฉด ๋ก ํ์ ์ ์ฌ์ฉํ์ง ๋ง๊ณ '?'๋ฅผ ์ฌ์ฉํ์.
๋ก ํ์ ์ ์ฌ์ฉํ๋ฉด ํ์ ๊ด๋ จ ์ค๋ฅ๋ฅผ '๋ฐํ์์' ๋ง์ฃผ์น ์ ์์์ ๋ช ์ฌํ์!
์์ปจ๋ ์ ๋ค๋ฆญ ํ์ ์ธ Set์ ๋นํ์ ์ ์์ผ๋์นด๋ ํ์ ์ Set<?>๋ค.
์ด๊ฒ์ด ์ด๋ค ํ์ ์ด๋ผ๋ ๋ด์ ์ ์๋ ๊ฐ์ฅ ๋ฒ์ฉ์ ์ธ ๋งค๊ฐ๋ณ์ํ Set ํ์ ์ด๋ค.
๋ค์์ ๋นํ์ ์ ์์ผ๋์นด๋ ํ์ ์ ์ฌ์ฉํด ์ ์ธํ ๋ฉ์๋์ด๋ค.
static int numElementsInCommon(Set<?> s1, Set<?> s2){
}
๋นํ์ ์ ์์ผ๋์นด๋ ํ์ ์ธ Set<?>์ ๋ก ํ์ ์ธ Set์ ์ฐจ์ด๋ ๋ฌด์์ผ๊น?
๋ฌผ์ํ๊ฐ ๋ฌด์ธ๊ฐ ๋ฉ์ง ์ผ์ ํด์ฃผ๋ ๊ฑธ๊น?
ํน์ง์ ๊ฐ๋จํ ๋งํ์๋ฉด ์์ผ๋์นด๋ ํ์ ์ ์์ ํ๊ณ , ๋ก ํ์ ์ ์์ ํ์ง ์๋ค.
๋ก ํ์ ์ปฌ๋ ์ ์๋ ์๋ฌด ์์๋ ๋ฃ์ ์ ์์ผ๋ ํ์ ๋ถ๋ณ์์ ํผ์ํ๊ธฐ ์ฝ๋ค.
๋ฐ๋ฉด, Collection<?>์๋ (null ์ธ์๋) ์ด๋ค ์์๋ ๋ฃ์ ์ ์๋ค.
์ฌ์ง์ด ๊บผ๋ผ ์ ์๋ ๊ฐ์ฒด์ ํ์ ๋ ์ ํ ์ ์ ์๋ค.
์ด๋ฌํ ์ ์ฝ์ ๋ฐ์๋ค์ผ ์ ์๋ค๋ฉด ์ ๋ค๋ฆญ ๋ฉ์๋(item 30)๋ ํ์ ์ ์์ผ๋์นด๋ ํ์ (item 31)์ ์ฌ์ฉํ๋ฉด ๋๋ค.
์์ผ๋์นด๋์ ์ ๊ฐ์ ๋ฃ์ ์ ์์๊น?
[์์ผ๋์นด๋์ ์ ๊ท ํ์
๋งค๊ฐ๋ณ์์ ์ฐจ์ด](https://github.com/JAVA-JIKIMI/EFFECTIVE-JAVA3/wiki/wildcard_vs_formalTypeParameter-JungHyunLyoo)
class ๋ฆฌํฐ๋ด์๋ ๋ก ํ์ ์ ์จ์ผ ํ๋ค.
์๋ฐ ๋ช ์ธ๋ class ๋ฆฌํฐ๋ด์ ๋งค๊ฐ๋ณ์ํ ํ์ ์ ์ฌ์ฉํ์ง ๋ชปํ๊ฒ ํ๋ค. (๋ฐฐ์ด๊ณผ ๊ธฐ๋ณธ ํ์ ์ ํ์ฉํ๋ค)
์๋ฅผ ๋ค์ด List.class, String[].class, int.class๋ ํ์ฉํ๊ณ
List.class์ List<?>.class๋ ํ์ฉํ์ง ์๋๋ค.
๋ฐํ์์๋ ์ ๋ค๋ฆญ ํ์ ์ ๋ณด๊ฐ ์ง์์ง๋ฏ๋ก instanceof ์ฐ์ฐ์๋ ๋นํ์ ์ ์์ผ๋ ์นด๋ ํ์ ์ด์ธ์ ๋งค๊ฐ๋ณ์ํ ํ์ ์๋ ์ ์ฉํ ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ ๋ก ํ์ ์ด๋ ๋นํ์ ์ ์์ผ๋์นด๋ ํ์ ์ด๋ instanceof๋ ์์ ํ ๋๊ฐ์ด ๋์ํ๋ค
๋นํ์ ์ ์์ผ๋์นด๋ ํ์ ์ ๊บพ์ ๊ดํธ์ ๋ฌผ์ํ๋ ์๋ฌด๋ฐ ์ญํ ์์ด ์ฝ๋๋ง ์ง์ ๋ถํ๊ฒ ๋ง๋ ๋ค.
์ด๋ฐ ๊ฒฝ์ฐ์ ์ฐจ๋ผ๋ฆฌ ๋ก ํ์ ์ ์ฐ๋ ํธ์ด ๊น๋ํ ์ ์๋ค.
๋ค์์ ์ ๋ค๋ฆญ ํ์ ์ instanceof๋ฅผ ์ฌ์ฉํ๋ ์ฌ๋ฐ๋ฅธ ์๋ค.
if (o instanceof Set) {
Set<?> s = (Set<?>) o;
}