JiwonDev

5-2 ์ œ๋„ค๋ฆญ, ๋ฐฐ์—ด๋ณด๋‹ค๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ, (+์Šˆํผํƒ€์ž… ๊ตฌํ˜„๋ฐฉ๋ฒ•)

by JiwonDev

 

  • ๐Ÿ’จ์ œ๋„ค๋ฆญ invariant(๋ฌด๋ณ€์„ฑ), covariant(๊ณต๋ณ€, extend), contravariant(๋ฐ˜๊ณต๋ณ€, super) ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. ํžŒํŠธ. ์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ” Item31. PECS - producer๋Š” extends๋กœ consumer๋Š” super๋กœ ์‚ฌ์šฉํ•˜์ž
    ๐Ÿ“Œ๊ณต๋ณ€ ์„ฑ์งˆ : A๊ฐ€ B์˜ ํ•˜์œ„ํƒ€์ž…์ผ ๋•Œ, ์ œ๋„ค๋ฆญ T<A> ๊ฐ€ T<B>์˜ ํ•˜์œ„ํƒ€์ž…์ธ๊ฐ€?
    ๐Ÿ“Œ๋ฐ˜๊ณต๋ณ€ ์„ฑ์งˆ: A๊ฐ€ B์˜ ํ•˜์œ„ํƒ€์ž…์ผ ๋•Œ, ์ œ๋„ค๋ฆญ T<B> ๊ฐ€ T<A>์˜ ํ•˜์œ„ ํƒ€์ž…์ธ๊ฐ€?
    ๐Ÿ“Œ๋ฌด๋ณ€์„ฑ ์„ฑ์งˆ: A๊ฐ€ B์˜ ํ•˜์œ„ํƒ€์ž…์ผ ๋•Œ, ์ œ๋„ค๋ฆญ T<A> ์™€ T<B> ํƒ€์ž…์ด ์„œ๋กœ ์•„๋ฌด๋Ÿฐ ๊ด€๊ณ„๊ฐ€ ์—†์œผ๋ฉด ๋ฌด๋ณ€์„ฑ.

Object number = new Number() // ์ฐธ๊ณ ๋กœ Integer์™€ Double์€ Number๋ฅผ ์ƒ์†ํ•œ๋‹ค.
Number integer = new Integer()
Number double = new Double()

List<Object> error = new List<Number> // ๋ฌด๋ณ€์„ฑ์ด๋ผ ๋ถˆ๊ฐ€๋Šฅ. ์ปดํŒŒ์ผ ์—๋Ÿฌ
List<Number> error = new List<Integer> // ๋ฌด๋ณ€์„ฑ์ด๋ผ ๋ถˆ๊ฐ€๋Šฅ. ์ปดํŒŒ์ผ ์—๋Ÿฌ
List<? extends Number> foo3 = new ArrayList<Number>();  // ์ž๊ธฐ์ž์‹ ์€ ๋‹น์—ฐํžˆ ๊ฐ€๋Šฅ
List<? extends Number> foo3 = new ArrayList<Integer>(); // ๊ณต๋ณ€์„ฑ ์žˆ์Œ. ๊ฐ€๋Šฅ
List<? extends Number> foo3 = new ArrayList<Double>();  // ๊ณต๋ณ€์„ฑ ์žˆ์Œ. ๊ฐ€๋Šฅ

List<? super Integer> foo3 = new ArrayList<Integer>();  // ์ž๊ธฐ์ž์‹ ์€ ๋‹น์—ฐํžˆ ๊ฐ€๋Šฅ
List<? super Integer> foo3 = new ArrayList<Number>();   // ๋ฐ˜๊ณต๋ณ€์„ฑ ์žˆ์Œ. ๊ฐ€๋Šฅ
List<? super Integer> foo3 = new ArrayList<Object>();   // ๋ฐ˜๊ณต๋ณ€์„ฑ ์žˆ์Œ. ๊ฐ€๋Šฅ

/* ์ฐธ๊ณ ๋กœ ๋‹ค์šด์บ์ŠคํŒ…์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉ์‹œ ์ปดํŒŒ์ผ์€ ๋˜์ง€๋งŒ, ๋Ÿฐํƒ€์ž„์— ClassCastException ๋ฐœ์ƒ. */
var parent = new Parent();
var child = parent // ClassCastException. ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด if(parent instanceof Child)๋ฅผ ์‚ฌ์šฉํ•ด์ค์‹œ๋‹ค.
// ์ƒ์‚ฐ์ž๋Š” ๊ณต๋ณ€์„ฑ์„ ์ œ๊ณตํ•ด์ฃผ๋ฉด ๋จ. extends
class ZooService{
    public void train(Cage<? extends Animal> cage){
        List<Animal> myCage = cage.getAll(); // Cage์—์„œ ๊บผ๋‚ด์„œ Animalํƒ€์ž…์œผ๋กœ ๋ฐ›์Œ
    }
}

ZooService zoo = new ZooService();
Cage<Tiger> tigerCage = new Cage<>();
Cage<Lion> lionCage = new Cage<>();

zoo.train(tigerCage) // ๊ณต๋ณ€์„ฑ์„ ์ง€์›ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— OK
zoo.train(lionCage)

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ์ ์€, ๋ฐ”์ดํŠธ์ฝ”๋“œ์ƒ์œผ๋กœ๋Š” ์ œ๋„ค๋ฆญ์„ ์“ฐ๋˜ ์•ˆ์“ฐ๋˜ ๋˜‘๊ฐ™๋‹ค๋Š” ์‚ฌ์‹ค. ์ปดํŒŒ์ผ ์‹œ์ ์— ํƒ€์ž…์ด ๊ฒฐ์ •๋จ.

Cage<..>์— ๋‹ด์•„์„œ ์ฃผ๋Š”๊ฑด ์–ด์ฐจํ”ผ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋กœ๋Š” Object๋ผ์„œ, ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์—†์Œ

๐Ÿงจ ๋ฌธ์ œ๋Š” ๊ทธ๋ƒฅ push(T animal) ์ด๋ผ๊ณ  ์ ์–ด๋ฒ„๋ฆฌ๋ฉด, T๊ฐ€ ์–ด๋–ค ํ•˜์œ„ํƒ€์ž…์ธ์ง€ ์•Œ ์ˆ˜ ์—†์–ด์„œ ์ปดํŒŒ์ผ ์—๋Ÿฌ๋ฅผ ๋„์›€.
์ œ๋„ค๋ฆญ์€ ํƒ€์ž…์„ ๋™์ ์œผ๋กœ ๋ณ€ํ™˜์‹œ์ผœ์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ์•„๋‹˜. <Tiger>๋Š” ๊ดœ์ฐฎ์ง€๋งŒ <? extends Animal>์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•จ.
์ œ๋„ค๋ฆญ์€ ์ปดํŒŒ์ผ์‹œ๊ฐ„์— ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ์œ„ํ•œ ๊ธฐ๋Šฅ์ž„. ํƒ€์ž…์ด ๋‹ค๋ฅด๋ฉด ๋‹น์—ฐํžˆ ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ.
ํ•˜์œ„ํƒ€์ž…์ธ Tiger๊ฐ€ ์ƒ์œ„์ธ Animal์€ ๋ณ€ํ™˜์ด ๊ฐ€๋Šฅํ•ด์„œ ์ƒ๊ด€์—†์Œ / ํ•˜์ง€๋งŒ Tiger๋ฅผ Lion์œผ๋กœ ๋ณ€๊ฒฝ? ๋ถˆ๊ฐ€๋Šฅ. ์ด๋Ÿฐ ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ปดํŒŒ์ผ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ์คŒ.

์ œ๋„ค๋ฆญ์„ <? extends Animal>์ด๋ผ Tiger, Lion ๋‘˜ ๋‹ค ๊ฐ€๋Šฅํ•œ๋ฐ? ๊ทธ๊ฑฐ ์บ์ŠคํŒ… ๋ถˆ๊ฐ€๋Šฅํ•˜์ž๋‚˜ ์œ„ํ—˜ํ•ด. ์ปดํŒŒ์ผ ์—๋Ÿฌ!

๊ทธ๋Ÿด ๋• ์ƒ์‚ฐ์ž(Cage) ์ฝ”๋“œ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ํ•˜์ง€๋ง๊ณ  ์†Œ๋น„์ž, ์ฆ‰ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋Š” ์ชฝ์—์„œ super๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•ด๊ฒฐํ•˜๋ฉด ๋จ.

Cage<Tiger> tigerCage = new Cage<>();

Cage<? super Tiger> cage = tigerCage; // ์ด๊ฑด <? extends Animal>๊ณผ ๊ฐ™์Œ.
cage.push(new Tiger()); // ์—ฌ๊ธฐ์„œ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค. cage.push(T Animal) ์ด ๊ฐ€๋Šฅํ•จ.

ํ•˜์œ„ํƒ€์ž…์€ Lion์œผ๋กœ ๊ฒฐ์ •ํ•˜๋ฉด, Dog๋กœ ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•จ. ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์Œ.

ํ•˜์ง€๋งŒ ์ƒ์œ„ํƒ€์ž…์€ Tiger๋ฅผ ๋„ฃ๋“  Animal์„ ๋„ฃ๋“  Object๋ฅผ ๋„ฃ๋“  ์ƒ๊ด€์—†์Œ. ์บ์ŠคํŒ…ํ•˜๋ฉด ๋˜๋‹ˆ๊นŒ(๋ฐ”์ดํŠธ์ฝ”๋“œ๋Š” object ์‚ฌ์šฉ) 
Producer-extends, Consumer-super. ์ค„์—ฌ์„œ ํŒจ-์“ฐ (PECS)

 

  • ๐Ÿ’จList<T>, ์ œ๋„ค๋ฆญ ํƒ€์ž…์ •๋ณด(super-type ํ† ํฐ)๋Š” ์•„๋ž˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์Šคํ”„๋ง์—์„œ๋Š” ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๊ตฌํ˜„์„ ํ•ด๋†จ๋Š”๋ฐ,  ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?
f.put(myList,  List<String>.class);

๐Ÿ“Œ ์šฐ์„ , Object๋กœ ๋ฐ›์•„์„œ ํƒ€์ž…๋ณ€ํ™˜์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์œผ๋‚˜, ๋งค์šฐ ์œ„ํ—˜ํ•œ ๋ฐฉ๋ฒ•์ž„. ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๋ฅผ ๋งŒ๋“ค๊ธฐ ์‰ฌ์›€. 

๐Ÿ“Œ ๊ทธ ๋Œ€์•ˆ์œผ๋กœ ๋‚˜์˜จ๊ฒŒ ํƒ€์ž…ํ† ํฐ, ์ฆ‰ Class<T> ๋ฅผ ๊ฐ™์ด ์ค˜์„œ ๊ทธ๊ฑธ๋กœ ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ๊ฒฐ์ •ํ•˜๊ณ , .cast()๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณ€ํ™˜.

 

 

๋ฐฐ์—ด๊ณผ ๋ฆฌ์ŠคํŠธ์˜ ์ฐจ์ด

์ž๋ฐ”์—๋„ ๋‹จ์ˆœ ๋ฐฐ์—ด์€ ์ œ๊ณตํ•ด์ฃผ๋‚˜, ๊ฐ€๋Šฅํ•˜๋ฉด ์ปฌ๋ ‰์…˜์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์ž.

๋ฌผ๋ก  ๊ธฐ๋Šฅ์ ์ธ ์ฐจ์ด - (๋ฐฐ์—ด์€ ํฌ๊ธฐ๋ฅผ ๋™์ ์œผ๋กœ ๋Š˜๋ฆด ์ˆ˜ ์—†์Œ)๋„ ์žˆ์ง€๋งŒ ๋ฐฐ์—ด์€ ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์—†๊ณ  ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ณต๋ณ€์„ฑ , ์ฆ‰ ํ•˜์œ„ํƒ€์ž…์„ ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค.

Object[] objects = new Long[1]; // ๊ฐ€๋Šฅ. ๋‹ค๋งŒ ๋Ÿฐํƒ€์ž„๋•Œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์Œ.

List<Object> list = new ArrayList<Long>(); //์ปดํŒŒ์ผ ์—๋Ÿฌ

๋ฆฌ์ŠคํŠธ๋Š” ์ƒ์œ„ํƒ€์ž…์˜ ๋ฐฐ์—ด์€ ํ•˜์œ„ํƒ€์ž…๋„ ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด, ๋ฐ์ดํ„ฐ ์‚ฝ์ž…์— ๋Œ€ํ•œ ์—๋Ÿฌ๋ฅผ ๋Ÿฐํƒ€์ž„์‹œ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•˜์ง€๋งŒ, ๋ฆฌ์ŠคํŠธ๋Š” ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด์„œ ์‰ฝ๊ฒŒ ์ฐพ์„์ˆ˜ ์žˆ๋‹ค.

 

๋ฌผ๋ก  ๋ฆฌ์ŠคํŠธ๋Š” ๋ž˜ํผํƒ€์ž…์ด๋ฏ€๋กœ ๋ฐฐ์—ด๋ณด๋‹ค ์†๋„๊ฐ€ ๋Š๋ฆฌ๋‹ค. ํ•˜์ง€๋งŒ Collection์€ ๋‚ด๋ถ€์ ์ธ ์ตœ์ ํ™”๊ฐ€ ์ด๋ฏธ ๋˜์–ด์žˆ๊ณ , ๋Œ€๋ถ€๋ถ„์˜ ์„œ๋น„์Šค์—์„œ ๋ฆฌ์ŠคํŠธ -> ๋ฐฐ์—ด๋กœ ์ตœ์ ํ™”๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋Š” ์—†๋‹ค. ํŠธ๋ ˆ์ด๋“œ ์˜คํ”„๋ฅผ ๊ณ ๋ คํ•˜์ž. ๋ฐฐ์—ด์˜ ์น˜๋ช…์ ์ธ ๋‹จ์ ์„ ๊ฐ€์ง€๋ฉด์„œ๊นŒ์ง€ ์ตœ์ ํ™”๊ฐ€ ํ•„์š”ํ•œ ์„œ๋น„์Šค์ธ๊ฐ€?

 

 

# ์ด์™•์ด๋ฉด ์ œ๋„ค๋ฆญ ํƒ€์ž…/ ์ œ๋„ค๋ฆญ ๋ฉ”์„œ๋“œ๋กœ ๋งŒ๋“ค์–ด๋ผ.

์œ„์˜ ๋ฐฐ์—ด vs ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ, ์ œ๋„ค๋ฆญ์€ ๋Ÿฐํƒ€์ž„์— ์•„๋ฌด๋Ÿฐ ์˜ํ–ฅ์„ ๋ผ์น˜์ง€ ์•Š๊ณ ๋„ ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. ์ƒˆ๋กœ์šด ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•  ๊ฐ์ฒด๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ํ˜•๋ณ€ํ™˜(์บ์ŠคํŒ…)์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ์ œ๋„ค๋ฆญ์œผ๋กœ ๋งŒ๋“ค ์ˆ˜๋Š” ์—†๋Š”์ง€ ๊ณ ๋ คํ•˜์ž.

 

 

# ๋ฆฌ์ŠคํŠธ์—์„œ ๊ณต๋ณ€์„ฑ (ํ•˜์œ„ํƒ€์ž… ๋ฐ›๊ธฐ)๊ฐ€ ํ•„์š”ํ•˜๋ฉด ํ•œ์ •์  ์™€์ผ๋“œ์นด๋“œ๋ฅผ ์‚ฌ์šฉ

<? extends T>์™€ <? super T> ๋ฅผ ์ œ๋„ค๋ฆญ์œผ๋กœ ์‚ฌ์šฉํ•˜์ž.

public class CustomObject<E> {

    private List<E> items;

    public void customAddAll(List<? extends E> items) { // E์™€ E์˜ ํ•˜์œ„๊ฐ์ฒด
        this.items.addAll(items);
    }

    public void copy(List<? super E> items){ // E์™€ E์˜ ์ƒ์œ„ ๊ฐ์ฒด
        items.addAll(this.items);
    }

    public void customRemoveAll(List<? extends E> items){
        this.items.removeAll(items);
    }
}

 

 

# ์ œ๋„ค๋ฆญ๊ณผ ๊ฐ€๋ณ€์ธ์ˆ˜(...)์„ ๊ฐ™์ด ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์‹ ์ค‘ํ•˜๋ผ.

์ž๋ฐ”์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐ€๋ณ€์ธ์ˆ˜(์ธ์ž ๊ฐœ์ˆ˜๋ฅผ ์œ ๋™์ ์œผ๋กœ) ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

์ด ๊ฒฝ์šฐ ์ œ๋„ค๋ฆญ ๊ฐ€๋ณ€์ธ์ˆ˜์— ๊ฐ’์„ ์ €์žฅํ•˜๋Š”๊ฑด ์•ˆ์ „ํ•˜์ง€ ์•Š๋‹ค. ClassCastException์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

static void dangerous(List<String>... stringLists) {
    Object[] objects = stringList; // ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    
    // ๋ฏธ์นœ์ง“์ด์ง€๋งŒ ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋ฉด ์ œ๋„ค๋ฆญ์˜ ์ปดํŒŒ์ผ ํƒ€์ž…๊ฒ€์ฆ์„ ๋ฌด์‹œํ•ด๋ฒ„๋ฆฐ๋‹ค.
    List<Integer> intList = List.of(42);
    objects[0] = intList;
    
    String s = stringList[0].get(0); // ์‚ฌ์šฉํ•˜๋Š” ์‹œ์ ์— ClassCastException ๋ฐœ์ƒ
}

 

๋ฌผ๋ก  ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฐฐ์—ด์„ ์™ธ๋ถ€์— ๋…ธ์ถœํ•˜์ง€์•Š๊ณ , ์‚ฌ์šฉ์— ์ฃผ์˜ํ•œ๋‹ค๋ฉด ํฐ ๋ฌธ์ œ์—†์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด ๊ฒฝ์šฐ์—๋Š” @SafeVarargs๋ฅผ ๋ฉ”์„œ๋“œ์— ๋ถ™์—ฌ์ฃผ์ž. ์ด๋Š” @SupressWarnings์™€ ๋น„์Šทํ•˜๊ฒŒ ์ปดํŒŒ์ผ ๊ฒฝ๊ณ ๋ฅผ ์ œ๊ฑฐํ•ด์ค€๋‹ค.

๋‹ค๋งŒ ๋ฐ˜๋“œ์‹œ ์•ˆ์ „ํ•˜๋‹ค๋Š”๊ฑธ ๋ณด์žฅํ•ด์ค˜์•ผํ•œ๋‹ค. @SafeVarargs๋Š” ํ‘œ์‹œํ•˜๋Š” ์šฉ๋„์ผ๋ฟ, ์–ด๋– ํ•œ ์ถ”๊ฐ€์ž‘์—…๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

public class Machine<T> {
    private List<T> versions = new ArrayList<>();

    @SafeVarargs
    public final void safe(T... toAdd) {
        for (T version : toAdd) {
            versions.add(version);
        }
    }
}

 

 

 

# ํƒ€์ž… ์•ˆ์ • ์ด์ข… ์ปจํ…Œ์ด๋„ˆ (ํƒ€์ž…์ •๋ณด Class<T>๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ํ•จ๊ป˜๋ฐ›๊ธฐ)

์ œ๋„ค๋ฆญ์—์„œ ์™€์ผ๋“œ์นด๋“œ๋ณด๋‹ค ํƒ€์ž…์„ ์œ ์—ฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์ž.

public class Favorites {

    private Map<Class<?>, Object> favorites = new HashMap<>();

    public <T> void putFavorite(Class<T> type, T instance) {
        //cast ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค!
        favorites.put(Objects.requireNonNull(type), type.cast(instance));
    }

    public <T> T getFavorite(Class<T> type) {
        //cast ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค!
        return type.cast(favorites.get(type));
    }
}
    Favorites f = new Favorites();

    f.putFavorite(String.class, "์ŠคํŠธ๋ง");
    f.putFavorite(Integer.class, 1);
    f.putFavorite(Long.class, 1L);
    
    // ๋ฌผ๋ก  ์•„๋ž˜์™€ ๊ฐ™์ด ์‹ค์ฒดํ™”๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•œ ์ œ๋„ค๋ฆญ์„ ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆœ ์—†๋‹ค.
    // ์—๋Ÿฌ - f.putFavorite(List<String>.class, new ArrayList<>());

์ œ๋„ค๋ฆญ๊นŒ์ง€ ํƒ€์ž…์œผ๋กœ ๋ฐ›๊ณ ์‹ถ๋‹ค๋ฉด ์Šˆํผํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

  1. ParameterizedType๋ฅผ ์‚ฌ์šฉ
  2. TypeFactory๋ฅผ ์‚ฌ์šฉ
//์Šˆํผํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ž…์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค!
    public <T> void putFavorite(TypeReference<T> valueTypeRef, T instance) {

        // ParameterizedType๋กœ ์บ์ŠคํŒ…ํ•˜์—ฌ Class<T>๋ฅผ ์–ป๋Š”๋‹ค!
        Class<T> tClass = ((Class<T>) ((ParameterizedType) valueTypeRef.getType()).getRawType());

        favorites.put(Objects.requireNonNull(tClass), Objects.requireNonNull(instance));
    }

    //์Šˆํผํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ž…์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค!
    public <T> T getFavorite(TypeReference<T> valueTypeRef) {

        // TypeFactory๋ฅผ ์ด์šฉํ•ด์„œ Class<T>๋ฅผ ์–ป๋Š”๋‹ค!
        Class<T> rawClass = (Class<T>) TypeFactory.type(valueTypeRef.getType()).getRawClass();

        return rawClass.cast(favorites.get(rawClass));
    }
    
    
    @Test
    public void ์ด์ข…_ํƒ€์ž…_์ปจํ…Œ์ด๋„ˆ_์‹ค์ฒดํ™”_๋ถˆ๊ฐ€_ํƒ€์ž…_์Šˆํผํƒ€์ž…_ํ† ํฐ() {
        //given
        Favorites f = new Favorites();

        // ์Šˆํผํƒ€์ž…์œผ๋กœ ๋„ฃ๋Š”๋‹ค!
        f.putFavorite(new TypeReference<List<String>>() {}, Collections.singletonList("์Šˆํผ ํƒ€์ž… ํ† ํฐ"));

        // ์Šˆํผํƒ€์ž…์œผ๋กœ ๊บผ๋‚ธ๋‹ค!
        List<String> strings = f.getFavorite(new TypeReference<List<String>>() {});

        //then
        assertEquals("์Šˆํผ ํƒ€์ž… ํ† ํฐ", strings.get(0));
    }

 

์ฐธ๊ณ ๋กœ ์Šคํ”„๋ง์—์„œ๋Š” ParameterizedTypeReference ๋ฅผ ์Šˆํผํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ๊ถ๊ธˆํ•˜๋‹ค๋ฉด ์•„๋ž˜๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•˜์ž.

https://homoefficio.github.io/2016/11/30/%ED%81%B4%EB%9E%98%EC%8A%A4-%EB%A6%AC%ED%84%B0%EB%9F%B4-%ED%83%80%EC%9E%85-%ED%86%A0%ED%81%B0-%EC%88%98%ED%8D%BC-%ED%83%80%EC%9E%85-%ED%86%A0%ED%81%B0/

 

ํด๋ž˜์Šค ๋ฆฌํ„ฐ๋Ÿด, ํƒ€์ž… ํ† ํฐ, ์ˆ˜ํผ ํƒ€์ž… ํ† ํฐ

ํด๋ž˜์Šค ๋ฆฌํ„ฐ๋Ÿด, ํƒ€์ž… ํ† ํฐ, ์ˆ˜ํผ ํƒ€์ž… ํ† ํฐ์ด ๊ธ€์€ ํ† ๋น„๋‹˜์˜ ๋ฐฉ์†ก ์ฑ„๋„์—์„œ ์†Œ๊ฐœํ•ด์ฃผ์‹  ์ˆ˜ํผ ํƒ€์ž… ํ† ํฐ์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ Oracle์˜ ๋ฆฌํ„ฐ๋Ÿด๊ณผ ๋Ÿฐํƒ€์ž„ ํƒ€์ž… ํ† ํฐ ํŠœํ† ๋ฆฌ์–ผ, ์ˆ˜ํผ ํƒ€์ž… ํ† ํฐ ๊ธฐ

homoefficio.github.io

https://www.youtube.com/watch?v=01sdXvZSjcI 

https://www.bsidesoft.com/2903

 

[java] ํ† ๋น„์˜ ๋ด„ TV๋ผ์ด๋ธŒ #2 - Bsidesoft co.

๋ณธ ์‹œ๋ฆฌ์ฆˆ์˜ ๊ฐœ์š” ๋ ์ˆ˜์žˆ๋Š” ๋Œ€๋กœ ํ† ๋น„๋‹˜์˜ ๋ฐฉ์†ก์„ ๋“ฃ๊ณ  ๊ทธ ํ›„๊ธฐ๋ฅผ ๋‚จ๊ฒจ๋ณผ๊นŒ ํ•ฉ๋‹ˆ๋‹ค. ํ† ๋น„๋‹˜์˜ ์ •๊ทœ๋ฐฉ์†ก ์ฃผ์†Œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๊ณ  ์ผ๋ฐ˜์ ์ธ ๋ฐฉ์†ก๊ณต์ง€๋Š” ํŽ˜๋ถ์ด๋‚˜ ์Šฌ๋ ‰์—์„œ ํ•˜์‹œ๋Š” ํŽธ์ž…๋‹ˆ๋‹ค. ํ† ๋น„์˜

www.bsidesoft.com

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ