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๋ผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์™€ 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๋ž€?

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๋กœ ์ ํ•ฉํ•˜๋‹ค๊ณ  ํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

์˜ค๋žœ๋งŒ์— ์˜์–ด๋ฌธ์žฅ์ข€ ์ฝ๋Š๋ผ ํ˜ผ์ญ๋‚ฌ๋‹ค

โš ๏ธ **GitHub.com Fallback** โš ๏ธ