보통사람

[Study-14주차] 제네릭(Generics) 본문

Study

[Study-14주차] 제네릭(Generics)

pej4303 2021. 2. 23. 22:59
  • 목표

    • 자바의 제네릭에 대해 학습하세요.

  • 학습할 것 (필수)

    • 제네릭 사용법

    • 제네릭 주요 개념 (바운디드 타입, 와일드 카드)

    • 제네릭 메소드 만들기

    • Erasure

 

0. 제네릭(Generics)

  • 어떤 타입이든 한 가지 타입으로 담을 수 있음

  • 클래스나 메소드에서 컴파일시 타입 체크를 해주는 기능을 함

  • 장점

    • 타입 안전성을 제공

    • 타입 체크와 형변환을 생략 할 수 있으므로 코드가 간결해짐

  • 다른 타입의 객체로 저장되는 것을 방지하며 원래의 타입과 다른 타입으로 형변환 되어 발생 할 수 있는 오류를 줄여줌

1. 제네릭 사용법

 

  • 선언하는 방법
public class MyGenerics<T> {
    // T : 타입변수 
    T name;
    
    public void setName(T name) {
        this.name = name;
    }
    
    public T getName() {
        return name;
    }
}

public class GenericsTest {

    public static void main(String[] args) {
        // String 타입만 가능함
        MyGenerics<String> my = new MyGenerics<>();
        my.setName("TEST");
        my.setName(123);    // 에러 발생
    }
}
  • 컴파일시 하위 버전과의 호환성 때문에 컴파일러가 제네릭 타입이 맞는지 소스를 체크하고 필요한 부분에 형변환을 넣어주고 제네릭 타입을 제거함 그래서 클래스 파일에는 제네릭 타입이 없음

2. 제네릭 주요 개념

 

  • 바운드 타입 매개변수(Bounded Type Parameters)

    • extends 키워드를 이용하여 타입의 제한을 주고자 할 때 사용함

  • Multiple Bounds

    • 여러개로 타입의 제한을 주고자 할 때 사용함

    • <T extends A & B& C>

  • 와일드 카드

    • 어떠한 타입도 들어 갈 수 있음
    • 제네릭 타입이 다른 것만으로는 재정의(오버로딩)이 성립하지 않기 때문에 와일드 카드가 고안됨
    • Object 타입과 다른 점이 없기 때문에 extends, super로  제한 할 수 있음
    • &를 사용 할 수 없음
<? extends T> : T와 그 자손들만 가능
<? super T>   : T와 그 조상들만 가능
<?>           : 모든 타입 가능 <? extends Object>와 동일
// 출처 - https://docs.oracle.com/javase/tutorial/java/generics/bounded.html

// 바운드 타입 매개변수
public <U extends Number> void inspect (U u) {
    System.out.println ( "T :"+ t.getClass (). getName ());
    System.out.println ( "U :"+ u.getClass (). getName ());
}

 

3. 제네릭 메소드 만들기

 

  • 클래스 생성자, static 메소드, 일반 메소드 모두 제네릭 허용됨
  • static 메소드의 경우 반환 타입도 제네릭 타입이어야 함
// 출처 - https://docs.oracle.com/javase/tutorial/java/generics/methods.html
public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
    return p1.getKey().equals(p2.getKey()) &&
    p1.getValue().equals(p2.getValue());
}

public class Pair<K, V> {

    private K key;
    private V value;

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public void setKey(K key) { this.key = key; }
    public void setValue(V value) { this.value = value; }
    public K getKey()   { return key; }
    public V getValue() { return value; }
}

 

4. Type Erasure

 

  • 일반 클래스, 인터페이스 및 메소드에서 컴파일시 제네릭 타입 유형은 없어지고 바인드된 유형으로 형변환이 됨
  • 타입의 제한이 없는 경우 또는 유형이 바인드되지 않은 경우는 Object로 변경함
// 출처 - https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html
public class Node<T> {

    private T data;
    private Node<T> next;

    public Node(T data, Node<T> next) {
        this.data = data;
        this.next = next;
    }

    public T getData() { return data; }
    ...
}

// T타입은 제한되지 않으므로 Object로 변경됨
public class Node {

    private Object data;
    private Node next;

    public Node(Object data, Node next) {
        this.data = data;
        this.next = next;
    }

    public Object getData() { return data; }
    ...
}
// 출처 - https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html
public class Node<T extends Comparable<T>> {

    private T data;
    private Node<T> next;

    public Node(T data, Node<T> next) {
        this.data = data;
        this.next = next;
    }

    public T getData() { return data; }
    ...
}

// T타입을 Comparable로 변경함
public class Node {

    private Comparable data;
    private Node next;

    public Node(Comparable data, Node next) {
        this.data = data;
        this.next = next;
    }

    public Comparable getData() { return data; }
    ...
}

 

 

※ 참조

 

 

Type Erasure (The Java™ Tutorials > Learning the Java Language > Generics (Updated))

The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Java Language Changes for a summary of updated

docs.oracle.com

 

'Study' 카테고리의 다른 글

[Study-13주차] I/O(입출력)  (0) 2021.02.12
[Study-12주차] 어노테이션(Annotation)  (0) 2021.01.31
[Study-11주차] Enum  (0) 2021.01.26
[Study-9주차] 예외 처리  (0) 2021.01.12
[Study-8주차] 인터페이스  (0) 2021.01.04