์ด๋ฒ ์ฅ(5์ฅ)๋ถํฐ๋ ์ ๋ค๋ฆญ์ ๋ค๋ฃฌ๋ค. ํน์๋ ์ ๋ค๋ฆญ์ ๋ํ ๊ธฐ๋ณธ ๊ฐ๋ ์ด ํ์ํ๋ค๋ฉด ์ด์ ๊ธ์ ๋จผ์ ๋ณด๊ณ ์ค๋๋ก ํ์.
1. ๋ก ํ์ (Raw Type) ๊ฐ๋ ๐ฝ
๋ก ํ์ ์ด๋ ์ ๋ค๋ฆญ ํ์ ์์ ํ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ํ ์ฌ์ฉํ์ง ์์ ๋๋ฅผ ๋งํ๋ค. ์๋ฅผ ๋ค์ด List<E>์ ๋ก ํ์ ์ List๋ค.
2. ๋ก ํ์ ์ ์ฌ์ฉํ๋ฉด ์ ๋๋ ์ด์ ๐พ
์ ๋ค๋ฆญ์ด ์๊ฒจ์ฃผ๋ ์์ ์ฑ๊ณผ ํํ๋ ฅ์ ๊ณ ๋ คํ ๋ ๋ก ํ์ ์ ์ ๋๋ก ์จ์๋ ์ ๋๋ค.
๋ก ํ์ ์ ์ฌ์ฉํ๋ ์ฝ๋(= ์ ๋ค๋ฆญ์ ์ฌ์ฉํ์ง ์๋ ์ฝ๋)์ ๋ก ํ์ ์ ์ฌ์ฉํ์ง ์๋ ์ฝ๋(= ์ ๋ค๋ฆญ์ ์ฌ์ฉํ๋ ์ฝ๋)๋ฅผ ๋น๊ตํด ๋ณด์.
๐ 1. ๋ก ํ์ ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ
๊ธฐ๋ณธ์ ์ธ ๋์์ numbers์ ์ซ์๋ฅผ ๋ฃ๊ณ ๋ฐ๋ณต๋ฌธ์ ํตํด ๋ค์ด๊ฐ ์ซ์๋ฅผ ํ์ธํ๋ ค๊ณ ํ๋ ์ฝ๋๋ค. ์ซ์๊ฐ ๋ค์ด๊ฐ์ผ ํ์ง๋ง ๋ฌธ์์ด์ด ๋ค์ด๊ฐ ๊ฒฝ์ฐ์ ์ด๋ป๊ฒ ๋์ํ๋์ง ์ดํด๋ณด์.
// ๋ก ํ์
์ฌ์ฉ O (Generic ์ฌ์ฉ X)
public static void main(String[] args) {
List numbers = new ArrayList();
numbers.add(10);
numbers.add("amenable");
for (Object number : numbers) {
System.out.println((Integer) number); // ClassCastException
}
}
๋ก ํ์ ์ ์ฌ์ฉํ๋ฉด ๋ฌธ์์ด์ด ๋ค์ด๊ฐ๋๋ผ๋ ์ปดํ์ผ์ด ๋๋ค. ํ์ง๋ง ๋ฐํ์์ ๋ฌธ์์ด์ Integer๋ก ๋ฐ๊ฟ ๋ ClassCastException์ด ๋ฐ์ํ๊ฒ ๋๋ค.
์ค๋ฅ๋ ๋ฐํ์ ์ํฉ์ด ์๋ ์ปดํ์ผํ ๋ ๋ฐ๊ฒฌํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์๋ฐ, ์์ ๊ฒฝ์ฐ๋ ๊ทธ๊ฒ์ ๋ง์กฑํ์ง ๋ชปํ๊ณ ์๋ค.
๐ 2. ๋ก ํ์ ์ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ
// ๋ก ํ์
์ฌ์ฉ X (Generic ์ฌ์ฉ O)
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add("amenable"); // Compile Error ๋ฐ์
for (Integer number : numbers) {
System.out.println(numbers);
}
}
๋ก ํ์ ์ ์ฌ์ฉํ์ง ์๊ณ ์ ๋ค๋ฆญ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ฅผ ์ดํด๋ณด์. ์ด ๊ฒฝ์ฐ์๋ ์ปดํ์ผ ์๋ฌ๊ฐ ๋ฐ๋ก ๋ฐ์ํ๋ค. numbers์๋ Integer๋ง ๋ฃ์ด์ผ ํ๋ ๊ฒ์ ์ปดํ์ผ๋ฌ๊ฐ ์ธ์งํ๊ณ ์๋๋ฐ ๋ฌธ์์ด(String)์ ๋ฃ์ผ๋ ค๊ณ ํด์ ์ปดํ์ผ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ด๋ค.
- ์ฆ, ์ด๋ ๊ฒ ์ปดํ์ผ ์์ ์ ์ค๋ฅ๋ฅผ ๋ฐ๊ฒฌํ ์ ์์ผ๋ฏ๋ก ์์ ์ฑ์ ํ๋ณดํ ์ ์๋ค.
- ๋ํ, 'List<Integer> numbers'๋ผ๊ณ ์ ์ธํ๋ค๋ฉด numbers์ Integer ํ์ ๋ง ๋ฃ์ด์ผ ํ๋ค๋ ๊ฒ์ ๋ฐ๋ก ์ ์ ์์ผ๋ฏ๋ก ํํ๋ ฅ ๋ํ ํ๋ณดํ ์ ์๋ค.
3. List VS List<Object> ๐ฟ
List ๊ฐ์ ๋ก ํ์ ์ ์ฌ์ฉํด์๋ ์ ๋๋, List<Object>์ฒ๋ผ ์์ ๊ฐ์ฒด๋ฅผ ํ์ฉํ๋ ๋งค๊ฐ๋ณ์ํ ํ์ ์ ๊ด์ฐฎ๋ค.
List๋ ์ ๋ค๋ฆญ ํ์ ์ด ์์ ์๋๊ณ , List<Object>๋ Object๋ฅผ ํ์ ๋งค๊ฐ ๋ณ์๋ก ๊ฐ์ง๊ธฐ ๋๋ฌธ์ด๋ค. ์ฆ, List<Object>๋ ๋ชจ๋ ํ์ ์ ํ์ฉํ๋ค๋ ์์ฌ๋ฅผ ์ปดํ์ผ๋ฌ์ ๋ช ํํ ์ ๋ฌํ๋ค.
๊ทธ๋์ ๋งค๊ฐ๋ณ์๋ก List๋ฅผ ๋ฐ๋ ๋ฉ์๋์ List<String>์ ๋๊ธธ ์๋ ์์ง๋ง, List<Object>๋ฅผ ๋ฐ๋ ๋ฉ์๋์๋ ๋๊ธธ ์ ์๋ค. List<String>์ ๋ก ํ์ ์ธ List์ ํ์ ํ์ ์ด์ง๋ง, List<Object>์ ํ์ ํ์ ์ ์๋๊ธฐ ๋๋ฌธ์ด๋ค.
List์ List<Object>๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๋ฅผ ๋น๊ตํด ๋ณด๋ฉด ์ฝ๊ฒ ์ดํดํ ์ ์์ ๊ฒ์ด๋ค.
๐ 1. List
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
unsafeAdd(strings, Integer.valueOf(27));
String s = strings.get(0); // ClassCastException
}
private static void unsafeAdd(List list, Object o) {
list.add(o);
}
ํด๋น ์ฝ๋์์ strings.get(0)์ ๊ฒฐ๊ณผ๋ฅผ ํ๋ณํ ํ๋ ค๊ณ ํ ๋ ClassCastException์ด ๋ฐ์ํ๋ค.
์ปดํ์ผํ ๋ ๋ฐ์ํ๋ ๊ฒ์ด ์๋ ๋ฐํ์์ ๋ฐ์ํ๋ค.
๐ 2. List<Object>
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
safeAdd(strings, Integer.valueOf(27)); // Compile Error
String s = strings.get(0);
}
private static void safeAdd(List<Object> list, Object o) {
list.add(o);
}
๋ฐ๋ฉด์ List<Object>๋ฅผ ์ฌ์ฉํ๋ฉด Compile Error๊ฐ ๋ฐ์ํ๋ฉด์ ์ปดํ์ผ์กฐ์ฐจ ๋์ง ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
4. Set VS Set<?> ๐
์์์ List<Object>๋ฅผ ์ฌ์ฉํ๋ฉด์ ์์์ ํ์ ์ ๋ชฐ๋ผ๋ ๋๋ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์ถ์ ๊ฒ์ด๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ๋ก ํ์ ์ด ์๋ ๋นํ์ ์ ์์ผ๋์นด๋ ํ์ (unbounded wildcard type)์ ์ฌ์ฉํ๋ ๊ฒ ์ข๋ค.
์ฆ, ์ ๋ค๋ฆญ ํ์ ์ ์ฐ๊ณ ์ถ์ง๋ง ์ค์ ํ์ ๋งค๊ฐ๋ณ์๊ฐ ๋ฌด์์ธ์ง ์ ๊ฒฝ ์ฐ๊ณ ์ถ์ง ์๋ค๋ฉด ๋ฌผ์ํ(?)๋ฅผ ์ฌ์ฉํ์. ์ด๊ฒ์ ์ด๋ค ํ์ ์ด๋ผ๋ ๋ด์ ์ ์๋ ๊ฐ์ฅ ๋ฒ์ฉ์ ์ธ ๋งค๊ฐ๋ณ์ํ ํ์ ์ด๋ค.
๊ทธ๋ฌ๋ฉด Set<?> ๋์ Set๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๊ฒฝ ์ฐ์ง ์์๋ ๋๋๋ฐ ์ Set<?>์ ๊ถ์ฅํ๋ ๊ฒ์ผ๊น? Set๊ณผ Set<?>๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๋ฅผ ๋น๊ตํด ๋ณด์.
๐ 1. Set
static int numElementsInCommon(Set s1, Set s2) {
s1.add("4"); // UnsupportedOperationException
int result = 0;
for (Object o1 : s1) {
if (s2.contains(o1)){
result++;
}
}
return result;
}
public static void main(String[] args) {
System.out.println(Numbers.numElementsInCommon(Set.of(1, 2, 3), Set.of(1, 2)));
}
์์ ์ฝ๋๋ Set์ธ s1๊ณผ s2์ ๊ณตํต์ ์ผ๋ก ์๋ ์ซ์์ ๊ฐ์๋ฅผ ์นด์ดํธํ๋ ค๊ณ ํ๊ณ ์๋ค. ํ์ง๋ง, ์ฝ๋์์ ํ์ธํ ์ ์๋ ๊ฒ์ฒ๋ผ ์ซ์๋ฟ๋ง ์๋๋ผ ๋ฌธ์์ด๋ ๋ฃ์ ์ ์๋ค. (s1.add("4"))
์ฝ๋์์ s1.add("1")์ ํ๋ ค๊ณ ํ ๋ UnsupportedOperationException ๋ฐ์ํ๋ค. ์ปดํ์ผํ ๋ ๋ฐ์ํ๋ ๊ฒ์ด ์๋ ๋ฐํ์์ ๋ฐ์ํ๋ค.
์ฆ, ๋ก ํ์ ์ปฌ๋ ์ ์ ์๋ฌด ์์๋ ๋ฃ์ ์ ์์ด์ ์์ ํ์ง ์์ ์ํฉ์ด๋ค.
๐ 2. Set<?>
static int numElementsInCommon(Set<?> s1, Set<?> s2) {
s1.add(4); // Compile Error
int result = 0;
for (Object o1 : s1) {
if (s2.contains(o1)){
result++;
}
}
return result;
}
public static void main(String[] args) {
System.out.println(Numbers.numElementsInCommon(Set.of(1, 2, 3), Set.of(1, 2)));
}
๋ฐ๋ฉด, Collection<?>์๋ null ์ธ์๋ ์ด๋ค ์์๋ ๋ฃ์ ์ ์์ผ๋ฏ๋ก ์์ ํ๋ค. s1.add(4)๊ฐ ์๋ ๊ฒฝ์ฐ Compile Error๊ฐ ๋ฐ์ํ๋ค.
๊ทธ๋์ ๊ฒฐ๊ตญ ์์ ์ฑ์ ๊ณ ๋ คํ์์ ๋ Set์ด ์๋ Set<?>์ ์ฌ์ฉํด์ผ ํ๋ค.
5. ์์ธ ๐ผ
๊ณ์ํด์ ๋ก ํ์ ์ ์ฌ์ฉํ์ง ๋ง๋ผ๊ณ ๋งํด์๋ค. ํ์ง๋ง ์ญ์ ๋ก ํ์ ์ ์ฐ์ง ๋ง๋ผ๋ ๊ท์น์๋ 2๊ฐ์ง ์์ธ๊ฐ ์กด์ฌํ๋ค.
๐ 1. class ๋ฆฌํฐ๋ด
class ๋ฆฌํฐ๋ด์๋ ๋ก ํ์ ์ ์จ์ผ ํ๋ค.
์๋ฐ ๋ช ์ธ๋ class ๋ฆฌํฐ๋ด์ ๋งค๊ฐ๋ณ์ํ ํ์ ์ ์ฌ์ฉํ์ง ๋ชปํ๊ฒ ํ๋ค. (๋ฐฐ์ด๊ณผ ๊ธฐ๋ณธ ํ์ ์ ํ์ฉํ๋ค.)
public class UserRawType<E> {
private E e;
}
----------
public static void main(String[] args) {
// ํ์ฉ X
System.out.println(UserRawType<Integer>.class);
// ํ์ฉ O
System.out.println(UserRawType.class);
}
์ฆ, List.class, String[].class, int.class๋ ํ์ฉํ๊ณ List<String>.class์ List<?>.class๋ ํ์ฉํ์ง ์๋๋ค.
๐ 2. instanceof ์ฐ์ฐ์
public class UserRawType<E> {
private E e;
}
----------
public static void main(String[] args) {
UserRawType<String> stringType = new UserRawType<>();
// ํ์ฉ O
System.out.println(stringType instanceof UserRawType<String>);
// ํ์ฉ O
System.out.println(stringType instanceof UserRawType);
}
์์ ์ฝ๋์ฒ๋ผ instanceof์ ์ ๋ค๋ฆญ์ ์ฌ์ฉํ๋ ๋ฐฉ์๊ณผ ๋ก ํ์ ์ ์ฌ์ฉํ๋ ๋ฐฉ์ ๋ ๋ค ์ฌ์ฉํ ์๋ ์๋ค. ๋ฐํ์์๋ ์ ๋ค๋ฆญ ํ์ ์ ๋ณด๊ฐ ์ง์์ง๋ฏ๋ก ๋ ๊ฐ ๋ชจ๋ ์์ ํ ๋๊ฐ์ด ๋์ํ๋ค.
๊ทธ๋ฌ๋ฏ๋ก ์ ๋ค๋ฆญ์ด ์๋ฌด๋ฐ ์ญํ ์์ด ์ฝ๋๋ง ์ง์ ๋ถํ๊ฒ ๋ง๋ค๊ณ ์์ผ๋ฏ๋ก ์ด๋ฐ ๊ฒฝ์ฐ์๋ ์ฐจ๋ผ๋ฆฌ ๋ก ํ์ ์ ์ฐ๋ ํธ์ด ๊น๋ํ๋ค.
ํด๋น ๊ธ์ ๋ฐฑ๊ธฐ์ ๋์ '์ดํํฐ๋ธ ์๋ฐ ์๋ฒฝ ๊ณต๋ต'์ ์ฐธ๊ณ ํ์์ต๋๋ค.