Generic

μ œλ„€λ¦­ (Generic)

μ •μ˜

  • 컴파일 νƒ€μž„μ— νƒ€μž…μ„ 체크해 μ£ΌλŠ” κΈ°λŠ₯

  • μ œλ„€λ¦­μ˜ μ‚¬μš©μ€ 두 κ°€μ§€ 이점을 κ°€μ§„λ‹€.

    1. μ§€μ •ν•œ νƒ€μž… μ΄μ™Έμ˜ νƒ€μž…μ„ κ°€μ§„ 데이터가 ν• λ‹Ήλ˜λ©΄ 컴파일 μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚¨λ‹€. λ”°λΌμ„œ, νƒ€μž… μ•ˆμ •μ„±μ„ 보μž₯ν•  수 μžˆλ‹€.

      • ex) List으둜 μ„ μ–Έν•˜λ©΄ String 이외 값이 λ“€μ–΄κ°€λ©΄ 컴파일 μ—λŸ¬κ°€ λ°œμƒ

    2. μ œλ„€λ¦­μœΌλ‘œ μ„ μ–Έν•œ 값은 λ¬΅μ‹œμ  ν˜•λ³€ν™˜μ΄ κ°€λŠ₯ν•˜λ‹€.

      • List ν•΄λ‹Ή ν•„λ“œλ‘œλΆ€ν„° κΊΌλ‚Έ 값은 ν˜•λ³€ν™˜ 없이도 String으둜 κ°„μ£Ό

      • λ‚΄λΆ€μ μœΌλ‘œ μ»΄νŒŒμΌλŸ¬κ°€ λͺ…μ‹œμ  ν˜•λ³€ν™˜μ΄ ν•„μš”ν•œ 경우 μΆ”κ°€ν•΄μ£ΌκΈ° λ•Œλ¬Έ

μ‚¬μš© 이유 (λͺ©μ )

  • μ œλ„€λ¦­ μ΄μ „μ—λŠ” μ–΄λ–€ μžλ£Œν˜•μΈμ§€ ν™•μ •λ˜μ§€ μ•Šμ•„ μ–΄λ–€ νƒ€μž…μ˜ 값을 λ„£λ“  컴파일 μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•Šμ•˜κ³ , λ§Œμ•½ 이λ₯Ό νŠΉμ • μžλ£Œν˜•μœΌλ‘œ μ΄μš©ν•˜κ³ μž ν•œλ‹€λ©΄ λͺ…μ‹œμ μœΌλ‘œ ν˜•λ³€ν™˜μ„ 해쀬어야 ν–ˆλ‹€.

    • κ·ΈλŸ¬λ‚˜ μ΄λŠ” λŸ°νƒ€μž„ μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚¬ κ°€λŠ₯성을 λ‚΄ν¬ν•˜λŠ”λ°, λŸ°νƒ€μž„ μ—λŸ¬λŠ” μ΅œλŒ€ν•œ 컴파일 μ—λŸ¬λ‘œ λŒλ¦¬λŠ” 것이 μ’‹λ‹€. 컴파일 μ—λŸ¬λŠ” ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜μ§€ μ•Šκ³ λ„ μ •μ •ν•˜λŠ” 것이 κ°€λŠ₯ν•΄ 개발 쀑에 κ°μ§€ν•˜κ³  μˆ˜μ •ν•  수 있기 λ•Œλ¬Έμ΄λ‹€. (λ˜ν•œ, μš”μ¦˜ λŒ€λΆ€λΆ„ IDEλŠ” μ»΄νŒŒμΌν•˜μ§€ μ•Šκ³ λ„ 컴파일 μ—λŸ¬λŠ” μ•Œλ € 쀌)

  • μ •λ¦¬ν•˜μžλ©΄, μ œλ„€λ¦­μ€ ⭐잘λͺ»λœ ν˜•λ³€ν™˜μ— μ˜ν•΄ λ°œμƒν•˜λŠ” λŸ°νƒ€μž„ μ—λŸ¬μΈ ClassCastException을 컴파일 νƒ€μž„μœΌλ‘œ λŒμ–΄μ˜€λ„λ‘ ν•˜λŠ” 역할을 μˆ˜ν–‰β­ν•œλ‹€. 이것이 μ œλ„€λ¦­μ„ μ‚¬μš©ν•˜λŠ” κ°€μž₯ 큰 이유(λͺ©μ )이닀.

μ œλ„€λ¦­ 적용

μ œλ„€λ¦­ 클래슀

  • 클래슀λ₯Ό μž‘μ„±ν•  λ•Œ νƒ€μž… λ³€μˆ˜λ₯Ό λͺ…μ‹œν•œ 것

  • 객체λ₯Ό 생성할 λ•Œ νƒ€μž… λ³€μˆ˜ μžλ¦¬μ— μ‹€μ œ νƒ€μž…μ„ μ§€μ •(λŒ€μž…)ν•  수 μžˆλ‹€.

  • 클래슀λͺ… μ˜†μ— <νƒ€μž… λ³€μˆ˜>λ₯Ό λͺ…μ‹œν•¨μœΌλ‘œμ¨ μ„ μ–Έ κ°€λŠ₯ν•˜λ©°, 클래슀 λ‚΄λΆ€μ˜ ν•„λ“œ νƒ€μž…, νŒŒλΌλ―Έν„° νƒ€μž…, λ°˜ν™˜ νƒ€μž…μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.

  • μ œλ„€λ¦­ 클래슀 μ„ μ–Έ μ‹œ λ‹€μŒμ— μœ μ˜ν•΄μ•Ό ν•œλ‹€.

    • μ œλ„€λ¦­ 클래슀 λ‚΄λΆ€μ—μ„œλ„ μ–΄λ–€ λ³€μˆ˜λ“  생성 μ‹œμ μ—μ„œλŠ” νƒ€μž… λ³€μˆ˜κ°€ 였면 μ•ˆ λœλ‹€. (λ‹Ήμ—°νžˆ 생성 μ‹œμ μ—λŠ” νƒ€μž…μ΄ 확정돼야 함)

    • static ν•„λ“œ λ˜λŠ” λ©”μ†Œλ“œμ—λŠ” νƒ€μž… λ³€μˆ˜λ₯Ό μ‚¬μš©ν•  수 μ—†λ‹€. (static ν•„λ“œ/λ©”μ†Œλ“œλŠ” λͺ¨λ“  μΈμŠ€ν„΄μŠ€κ°€ κ³΅μœ ν•˜λŠ” μš”μ†Œμ΄λ―€λ‘œ μΈμŠ€ν„΄μŠ€λ³„λ‘œ νƒ€μž…μ΄ 지정될 수 μ—†μŒ)

  • μ œλ„€λ¦­ 클래슀의 λŒ€ν‘œμ μΈ μ˜ˆμ‹œλ‘œλŠ” Collection의 List, Set, 그리고 Map 자료ꡬ쑰 등이 μžˆλ‹€.

    ex) ArrayListλŠ” JDK1.5μ—μ„œ μ œλ„€λ¦­ κΈ°λŠ₯이 μΆ”κ°€λ˜λ©΄μ„œ λ‹€μŒκ³Ό 같이 κ΅¬ν˜„λ˜μ—ˆλ‹€.

    public class ArarayList<E> extends AbstractList<E> {
    	
    	private transient E[] elementData;
    	
    	public boolean add(E o) { ... }
    
    	public E get(int index) { ... }
    
    }

μ œν•œλœ μ œλ„€λ¦­ 클래슀 (νƒ€μž… μ œν•œ)

  • νƒ€μž… λ³€μˆ˜λ₯Ό <T extends 클래슀>으둜 μ„€μ •ν•˜λ©΄ νƒ€μž… μ§€μ • μ‹œ νŠΉμ • νƒ€μž…(κ³Ό κ·Έ μžμ†)만 κ°€λŠ₯ν•˜κ²Œ νƒ€μž…μ„ μ œν•œν•  수 μžˆλ‹€.

    • <T extends μΈν„°νŽ˜μ΄μŠ€>의 κ²½μš°μ—λ„ implementsκ°€ μ•„λ‹Œ extendsλ₯Ό μ“΄λ‹€.

  • ⭐ 이와 같이 νƒ€μž…μ„ μ œν•œν•˜λ©΄ ν•΄λ‹Ή 클래슀/μΈν„°νŽ˜μ΄μŠ€μ˜ λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€λŠ” μž₯점이 μžˆλ‹€.

  • ex) λͺ¨λ“  νƒ€μž… 객체λ₯Ό μ €μž₯ν•  수 μžˆλŠ” Box와 과일 객체만 μ €μž₯ν•  수 μžˆλŠ” FruitBox

    class Box<T> {
    
    	List<T> list = new ArrayList<T>();
    
    	void add(T item) { list.add(item); }
    	T get(int i) { return list.get(i); }
    
    }
    
    // Box의 κΈ°λŠ₯을 κ·ΈλŒ€λ‘œ μ œκ³΅ν•˜λ˜ 였직 과일만 넣을 수 μžˆλŠ” 클래슀
    class FruitBox<T extends Fruit> extends Box<T> {}

μ™€μΌλ“œμΉ΄λ“œ

  • <T extends 클래슀λͺ…>은 클래슀의 μ„ μ–Έ μ‹œμ μ— μ‚¬μš©ν•˜λŠ” 것이고, μ™€μΌλ“œμΉ΄λ“œλŠ” 이와 같은 λ™μž‘μ„ ν•˜λ‚˜ μΈμŠ€ν„΄μŠ€ μ„ μ–Έ μ‹œμ μ— μ‚¬μš©ν•˜λŠ” 것이닀.

  • μ™€μΌλ“œμΉ΄λ“œλ₯Ό μ΄μš©ν•˜λ©΄ ν•˜λ‚˜μ˜ μ°Έμ‘°ν˜• λ³€μˆ˜κ°€ κ°€λŠ₯ν•œ νƒ€μž… λ²”μœ„ λ‚΄μ—μ„œ μ—¬λŸ¬ νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°ν•  수 μžˆλ‹€.

  • κ·ΈλŸ¬λ‚˜ μ£Όμ˜ν•  점은, μ–΄μ¨Œλ“  μ°Έμ‘°κ°€ κ°€λŠ₯ν•œ 것이 μ—¬λŸ¬κ°œμΌ 뿐 μ°Έμ‘°(생성 및 ν• λ‹Ή) μ‹œμ μ—λŠ” 단 ν•˜λ‚˜μ˜ νƒ€μž…μœΌλ‘œ μ œν•œλ˜μ–΄μ•Ό ν•œλ‹€λŠ” 것이닀.

  • νƒ€μž… μ œν•œ ν΄λž˜μŠ€μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ <? extends List> ν•˜λ©΄ μ–΄μ¨Œλ“  List둜 κ°„μ£Όν•˜μ—¬ List의 λ©”μ†Œλ“œ 이용 κ°€λŠ₯ν•˜λ‹€.

  • μ‚¬μš©ν•˜λ©΄ ν•΄λ‹Ή ν΄λž˜μŠ€μ™€ κ·Έ μžμ†λ“€λ§Œ 할당이 κ°€λŠ₯ν•˜λ‹€. - ν•΄λ‹Ή 클래슀둜 κ°„μ£Όν•˜κ³  μ΄μš©ν•  수 μžˆμœΌλ―€λ‘œ(λ‹€ν˜•μ„±) κ°€μž₯ 많이 μ‚¬μš©λœλ‹€.

  • μ‚¬μš©ν•˜λ©΄ ν•΄λ‹Ή ν΄λž˜μŠ€μ™€ κ·Έ μ‘°μƒλ“€λ§Œ 할당이 κ°€λŠ₯ν•˜λ‹€.

  • ex) λ™μΌν•œ μ°Έμ‘°ν˜• λ³€μˆ˜μ— νƒ€μž… μ œν•œμ„ λ§Œμ‘±ν•˜λŠ” μ—¬λŸ¬ νƒ€μž… ν• λ‹Ή κ°€λŠ₯

    class Product {}
    class Tv extends Product {}
    class SamsungTv extends Tv {}
    
    ArrayList<? extends Product> list = new ArrayList<Tv>();
    // κ°€λŠ₯. Product, TV, SamsungTv κ°€λŠ₯
    
    ArrayList<? super Product> list = new ArrayList<Tv>();
    // λΆˆκ°€λŠ₯. Product, Product의 λΆ€λͺ¨ ν΄λž˜μŠ€λ“€(Object λ“±) κ°€λŠ₯
  • μ™€μΌλ“œμΉ΄λ“œλŠ” λ©”μ†Œλ“œμ˜ λ§€κ°œλ³€μˆ˜ μ•ˆμ—μ„œλ„ μ‚¬μš© κ°€λŠ₯ν•˜λ©°, static λ©”μ†Œλ“œμ—μ„œλ„ μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€.

    static Juice makeJuice(FruitBox<? extends Fruit> box) {
    	// FruitBoxμ—λŠ” Fruit λ˜λŠ” κ·Έλ₯Ό μƒμ†ν•˜λŠ” μ–΄λ–€ 것도 λŒ€μž… κ°€λŠ₯
    }

μ œλ„€λ¦­ λ©”μ†Œλ“œ

  • λ©”μ†Œλ“œλ₯Ό μ •μ˜ν•  λ•Œ νƒ€μž… λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λŠ” 것이닀.

  • μ œλ„€λ¦­ ν΄λž˜μŠ€μ™€ 같이 μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€.

    • λ‹€λ₯Έ νƒ€μž… λ³€μˆ˜λͺ…을 μ‚¬μš©ν•  것을 ꢌμž₯ν•˜λ‚˜ 같은 λ³€μˆ˜λͺ…을 μ‚¬μš©ν•˜λ©΄ μ œλ„€λ¦­ λ©”μ†Œλ“œμ˜ νƒ€μž… λ³€μˆ˜κ°€ 더 μš°μ„ μ‹œλœλ‹€.

      • global variable보닀 local variable이 더 μš°μ„ κΆŒμ„ κ°–λŠ” 것과 μœ μ‚¬

  • μ œλ„€λ¦­ λ©”μ†Œλ“œμ˜ 영ν–₯ λ²”μœ„λŠ” ν•΄λ‹Ή λ©”μ†Œλ“œμ˜ νŒŒλΌλ―Έν„° 뿐이닀.

  • μ œλ„€λ¦­ λ©”μ†Œλ“œμ—μ„œμ˜ νƒ€μž…μ€ λŒ€λΆ€λΆ„ μƒλž΅μ΄ κ°€λŠ₯ν•˜λ‹€.

  • static λ©”μ†Œλ“œμ—λ„ μ‚¬μš©ν•  수 μžˆλ‹€. (λ©”μ†Œλ“œ 호좜 μ‹œλ§ˆλ‹€ νƒ€μž…μ„ κ²°μ •ν•˜λ―€λ‘œ)

  • μ œλ„€λ¦­ λ©”μ†Œλ“œλ₯Ό μ΄μš©ν•˜λŠ” 방식, μ™€μΌλ“œμΉ΄λ“œλ₯Ό μ΄μš©ν•˜λŠ” 방식은 μ„œλ‘œ 같은 의미둜 μ‚¬μš©λ  수 있으며, 이 경우 λ‘˜ 쀑 ν•˜λ‚˜λ₯Ό μ„ νƒν•΄μ„œ μ‚¬μš©ν•˜λ©΄ λœλ‹€.

    ex) μž„μ˜μ˜ 과일 νƒ€μž… 객체λ₯Ό λ°›μ•„ 주슀λ₯Ό λ§Œλ“€μ–΄ λ°˜ν™˜ν•˜λŠ” λ©”μ†Œλ“œ

    // μ œλ„€λ¦­ λ©”μ†Œλ“œλ₯Ό 이용
    static <T extends Fruit> Juice makeJuice(FruitBox<T> box) {
    }
    
    // μ™€μΌλ“œμΉ΄λ“œλ₯Ό 이용
    static Juice makeJuice(FruitBox<? extends Fruit> box) {
    }
    • λŒ€λΆ€λΆ„ μ™€μΌλ“œμΉ΄λ“œλ₯Ό μš°μ„ μ μœΌλ‘œ μ“°κ³ , μ“Έ 수 없을 λ•Œ λŒ€μ•ˆμœΌλ‘œ μ œλ„€λ¦­ λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.

Reference

Java의 정석 - ch 12. μ œλ„€λ¦­

Last updated