Java

[Effective Java] ์•„์ดํ…œ 28. ๋ฐฐ์—ด๋ณด๋‹ค๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ.

quedevel 2023. 3. 20. 11:01
728x90
๋ฐ˜์‘ํ˜•

๐ŸŽฏ ์•„์ดํ…œ 28. ๋ฐฐ์—ด๋ณด๋‹ค๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ.

๋ฐฐ์—ด๊ณผ ์ œ๋„ค๋ฆญ ํƒ€์ž…์—๋Š” ์ค‘์š”ํ•œ ์ฐจ์ด๊ฐ€ ๋‘ ๊ฐ€์ง€ ์žˆ๋‹ค.


1๏ธโƒฃ ๋ฐฐ์—ด์€ ๊ณต๋ณ€์ด์ง€๋งŒ, ์ œ๋„ค๋ฆญ์€ ๋ถˆ๊ณต๋ณ€์ด๋‹ค.

Sub๊ฐ€ Super์˜ ํ•˜์œ„ ํƒ€์ž…์ด๋ผ๋ฉด ๋ฐฐ์—ด Sub[]๋Š” ๋ฐฐ์—ด Super[]์˜ ํ•˜์œ„ ํƒ€์ž…์ด ๋œ๋‹ค.

๋ฐ˜๋ฉด, ์„œ๋กœ ๋‹ค๋ฅธ ํƒ€์ž… Type1, Type2๊ฐ€ ์žˆ์„ ๋•Œ, List<Type1>์€ List<Type2>์˜ ํ•˜์œ„ ํƒ€์ž…๋„ ์•„๋‹ˆ๊ณ  ์ƒ์œ„ ํƒ€์ž…๋„ ์•„๋‹ˆ๋‹ค.

์บก์ฒ˜7

์–ด๋Š ์ชฝ์ด๋“  Long์šฉ ์ €์žฅ์†Œ์— String์„ ๋„ฃ์„ ์ˆ˜๋Š” ์—†๋‹ค. ๋‹ค๋งŒ ๋ฐฐ์—ด์—์„œ๋Š” ๊ทธ ์‹ค์ˆ˜๋ฅผ ๋Ÿฐํƒ€์ž„์—์•ผ ์•Œ๊ฒŒ ๋˜์ง€๋งŒ, ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํŒŒ์ผํ•  ๋•Œ ๋ฐ”๋กœ ์•Œ ์ˆ˜ ์žˆ๋‹ค.


2๏ธโƒฃ ๋ฐฐ์—ด์€ ์‹ค์ฒดํ™”(reify)๋œ๋‹ค.

๋ฐฐ์—ด์€ ๋Ÿฐํƒ€์ž„์—๋„ ์ž์‹ ์ด ๋‹ด๊ธฐ๋กœ ํ•œ ์›์†Œ์˜ ํƒ€์ž…์„ ์ธ์ง€ํ•˜๊ณ  ํ™•์ธํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ์œ„ ์ฝ”๋“œ์— ๋ณด๋“ฏ Long๋ฐฐ์—ด์— String์„ ๋„ฃ์œผ๋ ค ํ•˜๋ฉด ArrayStoreException์ด ๋ฐœ์ƒํ•œ๋‹ค.

๋ฐ˜๋ฉด, ์ œ๋„ค๋ฆญ์€ ํƒ€์ž… ์ •๋ณด๊ฐ€ ๋Ÿฐํƒ€์ž„์—๋Š” ์†Œ๊ฑฐ(erasure)๋œ๋‹ค.

  • Item28.java
public class Item28 {
    public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        strings.add("que");
        strings.add("devel");
    }
}
  • Item28.java๋ฅผ ์ปดํŒŒ์ผํ•œ Item28.class

public class Item28 {
  public Item28() {
  }

  public static void main(String[] var0) {
      ArrayList var1 = new ArrayList();
      var1.add("que");
      var1.add("devel");
  }
}

์ด๋Ÿฌํ•œ ์†Œ๊ฑฐ๋Š” ์ œ๋„ค๋ฆญ์ด ์ง€์›๋˜๊ธฐ ์ „์— ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ์™€ ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋งค์ปค๋‹ˆ์ฆ˜์œผ๋กœ, ์ž๋ฐ”5๊ฐ€ ์ œ๋„ค๋ฆญ์œผ๋กœ ์ˆœ์กฐ๋กญ๊ฒŒ ์ „ํ™˜๋  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์คฌ๋‹ค.


๋ฐฐ์—ด์€ ์ œ๋„ค๋ฆญ ํƒ€์ž…, ๋งค๊ฐœ๋ณ€์ˆ˜ํ™” ํƒ€์ž…, ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

์ฆ‰, new List<E>, new List<String>[], new E[] ์‹์œผ๋กœ ์ž‘์„ฑํ•˜๋ฉด ์ปดํŒŒ์ผํ•  ๋•Œ ์ œ๋„ค๋ฆญ ๋ฐฐ์—ด ์ƒ์„ฑ ์˜ค๋ฅ˜๋ฅผ ์ผ์œผํ‚จ๋‹ค.
๊ทธ ์ด์œ ๋Š” ํƒ€์ž… ์•ˆ์ „ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๋ฅผ ํ—ˆ์šฉํ•œ๋‹ค๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™ ์ƒ์„ฑํ•œ ํ˜•๋ณ€ํ™˜ ์ฝ”๋“œ์—์„œ ๋Ÿฐํƒ€์ž„์— ClassCastException์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.


  • ์ œ๋„ค๋ฆญ ๋ฐฐ์—ด ์ƒ์„ฑ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ  - ์ปดํŒŒ์ผ๋˜์ง€ ์•Š๋Š”๋‹ค.
List<String>[] stringLists = new List<String>[1];   // (1)
List<Integer> intList = List.of(42);                // (2)
Object[] objects = stringLists;                     // (3)
objects[0] = intList;                               // (4)
String s = stringLists[0].get(0);                   // (5)

๐Ÿšฉ if. ์ œ๋„ค๋ฆญ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜๋Š” (1)์ด ํ—ˆ์šฉ๋œ๋‹ค๋ฉด?

1๏ธโƒฃ (2)๋Š” ์›์†Œ๊ฐ€ ํ•˜๋‚˜์ธ List<Integer>๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

2๏ธโƒฃ (3)์€ (1)์—์„œ ์ƒ์„ฑํ•œ List<String>์˜ ๋ฐฐ์—ด์„ Object ๋ฐฐ์—ด์— ํ• ๋‹นํ•œ๋‹ค. ๋ฐฐ์—ด์€ ๊ณต๋ณ€์ด๋‹ˆ ์•„๋ฌด ๋ฌธ์ œ์—†๋‹ค.

3๏ธโƒฃ (4)๋Š” (2)์—์„œ ์ƒ์„ฑํ•œ List<Integer>์˜ ์ธ์Šคํ„ด์Šค๋ฅผ Object ๋ฐฐ์—ด์˜ ์ฒซ ์›์†Œ๋กœ ์ €์žฅํ•œ๋‹ค. ์ œ๋„ค๋ฆญ์€ ์†Œ๊ฑฐ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„๋˜์–ด์„œ ์ด ์—ญ์‹œ ์„ฑ๊ณตํ•œ๋‹ค.

( ์ฆ‰, ๋Ÿฐํƒ€์ž„์—๋Š” List<Integer> ์ธ์Šคํ„ด์Šค์˜ ํƒ€์ž…์€ ๋‹จ์ˆœํžˆ List๊ฐ€ ๋˜๊ณ , List<Integer>[] ์ธ์Šคํ„ด์Šค์˜ ํƒ€์ž…์€ List[]๊ฐ€ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ (4)์—์„œ๋„ ArrayStoreException์„ ์ผ์œผํ‚ค์ง€ ์•Š๋Š”๋‹ค.)

4๏ธโƒฃ List<String> ์ธ์Šคํ„ด์Šค๋งŒ ๋‹ด๊ฒ ๋‹ค๊ณ  ์„ ์–ธํ•œ stringLists๋ฐฐ์—ด์—๋Š” ์ง€๊ธˆ List<Integer> ์ธ์Šคํ„ด์Šค๊ฐ€ ์ €์žฅ๋ผ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  (5)๋Š” ์ด ๋ฐฐ์—ด์˜ ์ฒ˜์Œ ๋ฆฌ์ŠคํŠธ์—์„œ ์ฒซ ์›์†Œ๋ฅผ ๊บผ๋‚ด๋ ค ํ•œ๋‹ค.

5๏ธโƒฃ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๊บผ๋‚ธ ์›์†Œ๋ฅผ ์ž๋™์œผ๋กœ String์œผ๋กœ ํ˜•๋ณ€ํ™˜ํ•˜๋Š”๋ฐ, ์ด ์›์†Œ๋Š” Integer์ด๋ฏ€๋กœ ๋Ÿฐํƒ€์ž„์— ClassCastException์ด ๋ฐœ์ƒํ•œ๋‹ค.

๋”ฐ๋ผ์„œ, ์ด๋Ÿฐ ์ผ์„ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด (1)์—์„œ ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋ฅผ ๋‚ด์•ผ ํ•œ๋‹ค.

์†Œ๊ฑฐ ๋งค์ปค๋‹ˆ์ฆ˜ ๋•Œ๋ฌธ์— ๋งค๊ฐœ๋ณ€์ˆ˜ํ™” ํƒ€์ž… ๊ฐ€์šด๋ฐ ์‹ค์ฒดํ™”๋  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…์€ List<?>์™€ Map<?,?> ๊ฐ™์€ ๋น„ํ•œ์ •์  ์™€์ผ๋“œ ์นด๋“œ ํƒ€์ž…๋ฟ์ด๋‹ค.

but, ๋ฐฐ์—ด์„ ๋น„ํ•œ์ •์  ์™€์ผ๋“œ์นด๋“œ ํƒ€์ž…์œผ๋กœ ๋งŒ๋“ค ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ์œ ์šฉํ•˜๊ฒŒ ์“ฐ์ผ ์ผ์€ ๊ฑฐ์˜ ์—†๋‹ค.

  • ์ƒ์„ฑ์ž์—์„œ ์ปฌ๋ ‰์…˜์„ ๋ฐ›๋Š” Chooser ํด๋ž˜์Šค
public class Chooser {

    private final Object[] choiceArray;

    public Chooser(Collection choiceArray) {
        this.choiceArray = choiceArray.toArray();
    }

    public Object choose(){
        Random rnd = ThreadLocalRandom.current();
        return choiceArray[rnd.nextInt(choiceArray.length)];
    }
}

  • ๋ฆฌ์ŠคํŠธ ๊ธฐ๋ฐ˜ Chooser - ํƒ€์ž… ์•ˆ์ „์„ฑ ํ™•๋ณด!
public class Chooser<T> {

    private final List<T> choiceArray;

    public Chooser(Collection<T> choiceArray) {
        this.choiceArray = new ArrayList<>(choiceArray);
    }

    public T choose(){
        Random rnd = ThreadLocalRandom.current();
        return choiceArray.get(rnd.nextInt(choiceArray.size()));
    }
}

์ฐธ๊ณ  ์ž๋ฃŒ

Joshua Bloch, ใ€ŽEffective Java 3/Eใ€, ๊ฐœ์•ž๋งต์‹œ ์˜ฎ๊น€, ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ธ์‚ฌ์ดํŠธ(2018)
http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788966262281&orderClick=LEa&Kc=

728x90
๋ฐ˜์‘ํ˜•