Generics

μ œλ„€λ¦­μ€ λ°μ΄ν„°μ˜ νƒ€μž…μ„ 클래슀 λ‚΄λΆ€μ—μ„œ μ§€μ •ν•˜λŠ” 것이 μ•„λ‹ˆλΌ μ™ΈλΆ€μ—μ„œ μ§€μ •ν•˜λŠ” κΈ°λ²•μœΌλ‘œ, 컴파일 μ‹œμ μ— κ°•λ ₯ν•œ νƒ€μž… 체크λ₯Ό μ§€μ›ν•˜λŠ” κΈ°λŠ₯이닀.

// μ œλ„€λ¦­ 클래슀(= μ œλ„€λ¦­ νƒ€μž…)
class Box<T> {

    private T t;

    public void set(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }
}

class Main {

    public static void main(String[] args) {
        Box<String> box = new Box<String>();
        box.set("Hello");
        String str = box.get();
    }
}

μ œλ„€λ¦­μ— μ‚¬μš©λ˜λŠ” μš©μ–΄

μ œλ„€λ¦­μ—μ„œ μ‚¬μš©λ˜λŠ” μš©μ–΄μ™€ μ˜λ―ΈλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

μš©μ–΄(Terminology)
μ˜ˆμ‹œ
μ„€λͺ…

μ œλ„€λ¦­ νƒ€μž…(Generic Type)

List<E>

νƒ€μž…μ„ νŒŒλΌλ―Έν„°λ‘œ κ°€μ§€λŠ” ν΄λž˜μŠ€λ‚˜ μΈν„°νŽ˜μ΄μŠ€

νƒ€μž… λ§€κ°œλ³€μˆ˜(Type Parameter)

<T>, <E>

μ œλ„€λ¦­ 선언에 μ‚¬μš©λœ λ§€κ°œλ³€μˆ˜

λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…(Parameterized Type)

List<String>

μ œλ„€λ¦­ νƒ€μž…μ— μ‹€μ œ νƒ€μž…μ„ λŒ€μž…ν•œ 것

둜 νƒ€μž…(Raw Type)

List

νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šμ€ 일반 νƒ€μž…(ν•˜μœ„ ν˜Έν™˜μ„±μ„ μœ„ν•΄ μ‘΄μž¬ν•˜λ‚˜ μ‚¬μš© μ§€μ–‘)

λΉ„ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œ

List<?>

λͺ¨λ“  νƒ€μž…μ΄ 올 수 μžˆμŒμ„ 의미

ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œ

List<? extends Number>

νŠΉμ • νƒ€μž…κ³Ό κ·Έ ν•˜μœ„/μƒμœ„ νƒ€μž…λ§Œ ν—ˆμš©

μž¬κ·€μ  νƒ€μž… ν•œμ •

<T extends Comparable<T>>

Tκ°€ μžμ‹ κ³Ό 비ꡐ κ°€λŠ₯ν•œ νƒ€μž…μ΄μ–΄μ•Ό 함을 의미

일반적으둜 μ‚¬μš©λ˜λŠ” νƒ€μž… νŒŒλΌλ―Έν„° λͺ…λͺ… κ·œμΉ™μ€ λ‹€μŒκ³Ό κ°™λ‹€.

νƒ€μž…
μ„€λͺ…

<T>

Type (일반적인 데이터 νƒ€μž…)

<E>

Element (μ»¬λ ‰μ…˜ μš”μ†Œ)

<K>

Key

<V>

Value

<N>

Number

μ œλ„€λ¦­μ˜ μ œν•œ

μ œλ„€λ¦­μ€ 컴파일 μ‹œμ μ— νƒ€μž…μ„ μ²΄ν¬ν•˜κ³  λŸ°νƒ€μž„μ—λŠ” νƒ€μž…μ„ μ§€μš°λŠ”(Erasure) λ°©μ‹μœΌλ‘œ λ™μž‘ν•˜κΈ° λ•Œλ¬Έμ— λͺ‡ κ°€μ§€ μ œμ•½μ΄ λ°œμƒν•œλ‹€.

static 멀버 μ‚¬μš© λΆˆκ°€

static ν•„λ“œλ‚˜ λ©”μ„œλ“œλŠ” ν΄λž˜μŠ€κ°€ λ‘œλ”©λ  λ•Œ λ©”λͺ¨λ¦¬μ— μ˜¬λΌκ°€λ―€λ‘œ, μΈμŠ€ν„΄μŠ€ 생성 μ‹œμ μ— κ²°μ •λ˜λŠ” μ œλ„€λ¦­ νƒ€μž… Tλ₯Ό μ‚¬μš©ν•  수 μ—†λ‹€.

μ œλ„€λ¦­ λ°°μ—΄ 생성 λΆˆκ°€

μ œλ„€λ¦­ λ°°μ—΄ νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜ 선언은 κ°€λŠ₯ν•˜μ§€λ§Œ, new T[10]κ³Ό 같이 배열을 μƒμ„±ν•˜λŠ” 것은 λΆˆκ°€λŠ₯ν•˜λ‹€.

  • 원인

    • new μ—°μ‚°μžλŠ” νž™ μ˜μ—­μ— λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•˜κΈ° μœ„ν•΄ 컴파일 μ‹œμ μ— νƒ€μž…μ˜ μ •ν™•ν•œ 크기λ₯Ό μ•Œμ•„μ•Ό 함

    • μ œλ„€λ¦­μ€ λŸ°νƒ€μž„μ— νƒ€μž…μ΄ μ†Œκ±°λ˜λ―€λ‘œ 크기λ₯Ό ν™•μ •ν•  수 μ—†μŒ

  • ν•΄κ²°

    • Object[] 배열을 μƒμ„±ν•œ λ’€ μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ ν˜•λ³€ν™˜ν•˜κ±°λ‚˜ ArrayList와 같은 μ»¬λ ‰μ…˜μ„ μ‚¬μš©

    • Reflection API의 Array.newInstance ν™œμš©

μ œλ„€λ¦­ ν΄λž˜μŠ€μ™€ νƒ€μž… ν•œμ •

μ œλ„€λ¦­ ν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€ 생성 μ‹œ νƒ€μž…μ„ λͺ…μ‹œν•΄μ•Ό ν•˜λ©°, extends ν‚€μ›Œλ“œλ₯Ό 톡해 λŒ€μž… κ°€λŠ₯ν•œ νƒ€μž…μ„ μ œν•œν•  수 μžˆλ‹€.

  • κΈ°λ³Έ μ‚¬μš©

    • Box<Apple> box = new Box<>(); (JDK 7λΆ€ν„° μƒμ„±μž μΈ‘ νƒ€μž… μƒλž΅ κ°€λŠ₯)

    • Box<Fruit> box = new Box<Apple>(); (λΆˆκ°€λŠ₯: μ œλ„€λ¦­μ€ λΆˆκ³΅λ³€)

  • μ œν•œλœ μ œλ„€λ¦­(extends)

    • <T extends Fruit>: Fruitκ³Ό κ·Έ μžμ†λ§Œ λŒ€μž… κ°€λŠ₯

    • <T extends Fruit & Eatable>: ν΄λž˜μŠ€μ™€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ™μ‹œμ— 상속/κ΅¬ν˜„ν•΄μ•Ό ν•˜λŠ” 경우 &둜 μ—°κ²° (ν΄λž˜μŠ€κ°€ λ¨Όμ € 와야 함)

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

μ œλ„€λ¦­μ„ μœ μ—°ν•˜κ²Œ μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ μ™€μΌλ“œμΉ΄λ“œ(?)λ₯Ό μ‚¬μš©ν•˜λ©°, νŠΉμ • νƒ€μž…μœΌλ‘œ μ œν•œν•˜κΈ° μœ„ν•΄μ„  ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

  • <? extends T> : T와 κ·Έ μžμ†λ“€λ§Œ κ°€λŠ₯

    • 데이터λ₯Ό κΊΌλ‚΄μ˜€λŠ”(Produce) μ—­ν• λ§Œ ν•  λ•Œ μ‚¬μš©

    • T와 κ·Έ μžμ†λ“€λ§Œ κ°€λŠ₯ν•˜λ―€λ‘œ, κΊΌλ‚Έ λ°μ΄ν„°λŠ” μ΅œμ†Œν•œ Tμž„μ΄ 보μž₯(read μ•ˆμ „)

    • 데이터λ₯Ό λ„£λŠ” 것은 λΆˆκ°€λŠ₯(ꡬ체적인 ν•˜μœ„ νƒ€μž…μ„ μ•Œ 수 μ—†κΈ° λ•Œλ¬Έ)

  • <? super T> : T와 κ·Έ μ‘°μƒλ“€λ§Œ κ°€λŠ₯

    • 데이터λ₯Ό μ €μž₯ν•˜λŠ”(Consume) μ—­ν• λ§Œ ν•  λ•Œ μ‚¬μš©

    • T νƒ€μž…μ˜ 객체λ₯Ό μ•ˆμ „ν•˜κ²Œ μ €μž₯ κ°€λŠ₯(write μ•ˆμ „)

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

클래슀의 μ œλ„€λ¦­ νƒ€μž…κ³Ό λ³„κ°œλ‘œ λ©”μ„œλ“œ λ ˆλ²¨μ—μ„œ 독립적인 μ œλ„€λ¦­ νƒ€μž…μ„ μ •μ˜ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆλ‹€.

Generic Type Erasure

μ œλ„€λ¦­ νƒ€μž…μ€ 컴파일 μ‹œμ—λ§Œ μœ νš¨ν•˜κ³ , 컴파일 ν›„μ—λŠ” λŸ°νƒ€μž„ μ€‘μ—λŠ” νƒ€μž… 정보가 μ‚¬λΌμ§€κ²Œ λœλ‹€.

  1. νƒ€μž… 경계 제거

    • <T extends Fruit>λŠ” Fruit둜 μΉ˜ν™˜

    • <T>와 같이 μ œν•œμ΄ μ—†μœΌλ©΄ Object둜 μΉ˜ν™˜

  2. νƒ€μž… μΊμŠ€νŒ… μΆ”κ°€

    • νƒ€μž… μ•ˆμ •μ„±μ„ μœ„ν•΄ μš”μ†Œλ₯Ό μ°Έμ‘°ν•˜λŠ” 지점에 μ μ ˆν•œ μΊμŠ€νŒ… μ½”λ“œλ₯Ό μ»΄νŒŒμΌλŸ¬κ°€ μžλ™ μ‚½μž…

  3. λΈŒλ¦¬μ§€ λ©”μ„œλ“œ(Bridge Method) 생성

    • λ‹€ν˜•μ„±μ„ μœ μ§€ν•˜κΈ° μœ„ν•΄ μ»΄νŒŒμΌλŸ¬κ°€ λ‚΄λΆ€μ μœΌλ‘œ λΈŒλ¦¬μ§€ λ©”μ„œλ“œλ₯Ό 생성할 수 있음

μ΄λŸ¬ν•œ μ†Œκ±° νŠΉμ§• λ•Œλ¬Έμ— λŸ°νƒ€μž„μ— μ œλ„€λ¦­ νƒ€μž…μ„ instanceof둜 κ²€μ‚¬ν•˜κ±°λ‚˜, .class둜 νƒ€μž…μ„ μ•Œμ•„λ‚΄λŠ” 것은 λΆˆκ°€λŠ₯ν•˜λ‹€.

참고자료

Last updated

Was this helpful?