티스토리 뷰

제네릭의 의미

제네릭 클래스, 제네릭 인터페이스, 제네릭 메소드

-클래스, 인터페이스, 메소드를 정의할 때 타입 매개변수(타입 파라미터)를 선언하고 사용할 수 있음


제네릭을 사용하는 이유

- 자료형을 한정함으로써 컴파일 시점에 자료형 검사가 가능

 * 실행 오류를 찾아 고치는 것은 어려움

- 캐스트(형변환) 연산자의 사용이 불필요

- 여러 유형에 걸쳐 동작하는 일반화된 클래스/메소드를 정의할 수 있음


ArrayList 클래스는 List 인터페이스를 구현한 클래스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ArrayList<E> implements List<E> … {
    boolean add(E e) {
        …
    }
 
    E get(int index) {
        …
    }
 
    E remove(int index) {
        …
    }
 
    …
}
cs


1
2
3
4
5
6
List list1 = new ArrayList();
list1.add("hello");
String s1 = (String)list1.get(0); // 형변환 필요
List<String> list2 = new ArrayList<String>();
list2.add("hello");
String s2 = list2.get(0); //형변환이 필요 없음
cs



제네릭 클래스

클래스 정의에서 타입 파라미터를 선언함

- 클래스를 사용할 때는 타입을 명시해야 함

- 필드의 자료형, 메소드 반환형, 인자의 자료형으로 사용할 수 있음


타입 파라미터는 참조형만 가능함


컴파일 할 때, 명확한 타입 검사를 수행할 수 있음

- 메소드 호출시 인자의 유형이 맞는지

- 메소드 호출의 결과를 사용할 때 유형이 맞는지


자료형을 매개변수로 가지는 클래스와 인터페이스를 제네릭 타입이라고 함



제네릭 클래스 정의

문법

1
class 클래스이름<T1, T2, …> { … }
cs

 

- 클래스 정의에서 클래스 이름의 오른편, 각 괄호 < > 안에 타입 파라미터를 표시함

- 컴마(,)로 구분하여 여러 개의 타입 파라미터를 지정할 수 있음

- 타입 파라미터는 타입을 전달 받기 위한 것

- 타입 파라미터의 이름은 관례적으로 E, K, V, N, T … 을 사용함


1
2
3
4
5
6
7
8
9
10
11
class Data {
    private Object object;
 
    public void set(Object object) {
        this.object = object;
    }
 
    public Object get() {
        return object;
    }
}
cs


1
2
3
4
5
6
7
8
9
10
11
class Data2<T> {
    private T t;
 
    public void set(T t {
        this.t = t;
    }
 
    public T get() {
        return t;
    }
}
cs



제네릭 클래스의 사용

제네릭 타입과 자료형 검사

- 제네릭 타입을 사용하지 않으면 컴파일 시점에서 오류를 검출하지 못함


의미가 명확하면 생성자 호출 시, 괄호만 사용할 수 있음


1
Data2<String> b3 = new Data2<>();
cs


1
2
3
4
5
6
7
8
9
public class GenericsTest2 {
    public static void main(String args[]) {
        Data2<String> data = new Data2<String>();
        Integer i = new Integer(20);
        data.set(i); // 컴파일 오류
        String s = (String)data.get();
        … …
    }
}
cs



제네릭 인터페이스를 구현하는 제네릭 클래스

2개의 타입 매개변수(K와 V)를 가지는 클래스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
interface Pair<K, V> {
    public K getKey();
    public V getValue();
}
 
class OrderedPair <K, V> implements Pair <K, V> {
    private K key;
    private V value;
 
    public OrderedPair(K key, V value) {
        this.key = key;
        this.value = value;
    }
 
    public K getKey() {
        return key;
    }
 
    public V getValue() {
        return value;
    }
}
 
public class MultipleType {
    public static void main(String args[]) {
        Pair <String, Integer> p1;
        p1 = new OrderedPair <> ("Even"8);
        Pair <StringString> p2;
        p2 = new OrderedPair <> ("hello""java");
        … …
    }
}
cs



제네릭 타입을 상속/구현하는 일반 클래스

제네릭 인터페이스를 구현하는 일반 클래스

- 클래스를 정의할 때 제네릭 인터페이스의 자료형을 지정하면 됨


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class MyPair implements Pair<String, Integer> {
    private String key;
    private Integer value;
 
    public MyPair(String key, Integer value) {
        this.key = key;
        this.value = value;
    }
 
    public String getKey() {
        return key;
    }
 
    public Integer getValue() {
        return value;
    }
}
 
public class ClassFromGeneric {
    public static void main(String args[]) {
        MyPair mp = new MyPair("test"1);
        … …
    }
}
cs



Raw 타입

제네릭 타입을 일반 타입처럼 사용하는 경우의 제네릭 타입을 지칭하는 용어


1
Data2 data = new Data2("hello");
cs

- 이때 Data2는 제네릭 타입 Data2<T>의 raw 타입

- 자료형을 Object로 처리함



공지사항
최근에 올라온 글
Total
Today
Yesterday