wildcard_vs_formalTypeParameter JungHyunLyoo - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
์ค๋์๊ฐ ๋ค๊ฐ์ด ๊ณ ๋ฏผํ๋ <์์ผ๋์นด๋์ ์ ๊ท ํ์ ๋งค๊ฐ๋ณ์ T์ ์ฐจ์ด>์ ๋ํด
๋ต์ ์ป์ ๊ฒ ๊ฐ๋ค.
ibm ๊ฐ๋ฐ์ ํ์ด์ง์์ ๋์์ ์ป์ ์ ์์๋ค.
(https://www.ibm.com/developerworks/library/j-jtp04298/index.html)
์ ํ์ด์ง์ Contents > Wildcard capture ์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ด์ฉ์ด ๋ฑ ์์๋ค.
๋จผ์ Box๋ผ๋ ์ธํฐํ์ด์ค์ Box๋ฅผ reboxํ๋ ๋ฉ์๋๊ฐ ์๋ค.
public interface Box<T> {
T get();
void put(T element);
}
public void rebox(Box<?> box) {
box.put(box.get());
}
rebox ๋ฉ์๋๋ฅผ ํธ์ถํด๋ณธ๋ค๊ณ ์๊ฐํด๋ณด์.
์ ๋ฉ์๋์ ํธ์ถ๋ถ๊ฐ ์ปดํ์ผ ๋ ๋ ๋งค๊ฐ๋ณ์์ ์์ผ๋์นด๋ ํ์ ์ด ๊ฒฐ์ ๋๋ค.
๊ทธ๋ฆฌ๊ณ box๋ด์ ๊ฐ์ฒด๋ฅผ getํ ํ ๋ค์ putํ๋ค.
๋ณ๋ค๋ฅธ ์ค๋ฅ๊ฐ ์์ ๊ฒ ๊ฐ์ง๋ง ์ฌ์ค ๋ค์๊ณผ ๊ฐ์ ์๋ฌ๊ฐ ๋ฌ๋ค.
Rebox.java:8: put(capture#337 of ?) in Box<capture#337 of ?> cannot be applied
to (java.lang.Object)
box.put(box.get());
^
capture#337 of ?
์ด ์ค๋ฅ๊ฐ ๋ฌด์์ ์๋ฏธํ ๊น??
์ปดํ์ผ๋ฌ๋ ์์ผ๋์นด๋ ๋งค๊ฐ ๋ณ์๋ฅผ ๋ง๋๋ฉด(rebox ๋ฉ์๋์ box ํ๋ผ๋ฏธํฐ์ ๊ฐ์)
Box ํํ์ ๋ง์ถ ์ ์๋ ํน์ ํ T๋ฅผ ์์ฑํ๋ค. (์์ญํจ)
<์๋์ ๋ฌธ์ฅ>
When the compiler encounters a variable with a wildcard in its type, such as the box parameter of rebox(),
it knows that there must have been some T for which box is a Box<T>. It does not know what type T represents, but it can
create a placeholder for that type to refer to the type that T must be.
์ปดํ์ผ๋ฌ๊ฐ ์์ผ๋์นด๋๋ฅผ ์ด์ฉํด ์์ฑํ๋ ๊ทธ ํน์ T๋ค์ capture๋ผ๊ณ ํ๋ค!
์ ๋ฉ์๋์ ๊ฒฝ์ฐ์, ์ปดํ์ผ๋ฌ๋ "capture#337 of ?" ๋ผ๋ capture๋ฅผ ์์ฑํ ๊ฒ์ด๋ค.
<์ฐธ๊ณ >
์ปดํ์ผ๋ฌ๋ ๋ง๋๋ ๋ชจ๋ ? ๋ง๋ค ๋
๋ฆฝ์ ์ธ capture๋ฅผ ์์ฑํ๋ค.
์๋ฅผ๋ค์ด (Pair<?,?> x, Pair<?,?> y) ๋ผ๋ ๋งค๊ฐ ๋ณ์๊ฐ ์๋ค๋ฉด, 4๊ฐ์ ๋
๋ฆฝ์ ์ธ capture๊ฐ ์์ฑ๋๋ค.
๊ฐ ? ์๋ ์ฐ๊ด์ฑ์ด ์๊ธฐ ๋๋ฌธ.(์ฐ๊ด์ฑ์ด ์์ผ๋ฉด ๊ฐ์ capture๊ฐ ์ง์ ๋๋๋ณด๋ค)
์ ์๋ฌ ๋ฉ์ธ์ง๋ "์๋ ๋ ํ์ ์ด ๋น๊ต ๊ฐ๋ฅํ์ง ํ์ธ ํ ์ ์๊ธฐ ๋๋ฌธ์ put์ ํธ์ถํ ์ ์๋ค"๋ ๊ฒ์ ์๋ฏธํ๋ค.
-
put์ ์ ๋ฌ๋ ์ค์ ํ๋ผ๋ฏธํฐ์ ํ์ ( get()์ return ํ์ ์ธ Object )
-
formal parameter ํ์ ( ?๊ฐ ๋ณํ๋๋ capture#337 of ? )
? ๋ ์ ์ด์ ? extends Object๋ฅผ ์๋ฏธํ๋ฏ๋ก ์ปดํ์ผ๋ฌ๋ Object๋ฅผ ๋ฐํ ํ์ ์ผ๋ก ์ธ์ํ๋ค.
(์ด ๊ฒฝ์ฐ์ ๋ ์ ํํ๋ ? extends Object๋ณด๋จ capture#337 of ? extends Object์ธ ๊ฒ ๊ฐ๋ค๊ณ '์ถ์ธก'ํ๋ค.)
๊ฒฐ๊ตญ์ ์ ๋ ฅ๋๋ ํ์ ๊ณผ ๋ฐ๋ ํ์ ์ ํธํ์ด ์๋ง์ ์คํ ๋ถ๊ฐํ๋ค๋ ๊ฒ!!
private void reboxWildcard(Box<?> box) {
Object o = box.get();//๋ฌด์กฐ๊ฑด Object ํ์
์ผ๋ก๋ง ์ฐธ์กฐ ๊ฐ๋ฅ
box.put(o);//capture ํํ๋ก ํ๋ณํ ํ ๋ฐฉ๋ฒ์ด ์๊ธฐ ๋๋ฌธ์ put ๋ถ๊ฐ๋ฅ -> ์ปดํ์ผ ์๋ฌ๋จ!!!!!!!!!!!!!
}
private <T> void reboxT(Box<T> box) {
Object o = box.get();//Object ํ์
์ฐธ์กฐ ๊ฐ๋ฅ
box.put((T) o);
T o2 = box.get();//๋งค๊ฐ๋ณ์ ํ์
์ผ๋ก๋ ์ฐธ์กฐ ๊ฐ๋ฅ
box.put(o2);
}
๊ฒฐ๊ตญ ์์ผ๋์นด๋๋ก ๋งค๊ฐ ๋ณ์๋ฅผ ์ ์ธํ ๊ฒฝ์ฐ, get์ ์ผ๋ง๋ ์ง ํ ์ ์๋ค. Object๋ก ๋ฐ์์ ์ธ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ง๋ง set, put ๋ฑ์ ํ ์ ์๋ค. capture#337 of ? ํ์ ๊ณผ ๊ฐ์ ํํ๋ก ํ๋ณํ์ ํด์ผ ์ ์ฅํ ์ ์๋๋ฐ
์ ํํ๋ ์ค์ ํธ์ถ๋ถ๊ฐ ์ปดํ์ผ๋๋ ์์ ์ ์ ํด์ง๊ธฐ ๋๋ฌธ์(์ถ์ธก) ์ฝ๋๋ก ์ด์ฐ ๋ฃ์ ๋ฐฉ๋ฒ์ด ์๊ธฐ ๋๋ฌธ.
๋ฐ๋ฉด ์ ๊ท ํ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ๋ฉด get์ ๋ฌผ๋ก ์ด๊ณ set, put๋ ํ ์ ์๋ค.
์ฝ๋๋ฅผ ์์ฑํ ๋, T์ ๊ฐ์ ์ ์ฅํ ํ์ ์ ๋ช ํํ ์ ์ ์๊ธฐ ๋๋ฌธ
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ์ ์ฅ์์ ๋ฐ๋ผ๋ณธ๋ค๋ฉด, ์์ผ๋์นด๋๋ฅผ ์ฌ์ฉํ๋ ๋ฉ์๋๋
๋ด๋ถ์์ null ์ด์ธ์ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ์ ์๊ธฐ ๋๋ฌธ์ ์กฐ๊ธ ๋ ์์ฌ(?)ํ๊ณ ์ฌ์ฉํ ์ ์์ ๋ฏ ํ๋ค.
๊ทธ๋์ ์์ผ๋์นด๋๋ฅผ ์ฌ์ฉํ๋ ๋ฉ์๋๋ ๋ด๋ถ์์ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ์ ์๊ธฐ ๋๋ฌธ์
public api๋ก ์ ํฉํ๋ค๊ณ ํ๋ ๊ฒ ๊ฐ๋ค.
์ค๋๋ง์ ์์ด๋ฌธ์ฅ์ข ์ฝ๋๋ผ ํผ์ญ๋ฌ๋ค