2 분 소요

자바에서는 다양한 종류의 클래스와 인터페이스를 제공하고 있다. 이런 클래스와 인터페이스를 내부 맴버에서 활요하는 클래스를 작성하고자 할 때는 제공되는 클래스나 인터페이스의 다양성 만큼이나 많은 가짓수의 클래스를 생성해야 한다. 이러한 비효율성을 한 번에 해결하는데 필요한 문법 요소가 바로 ‘제네릭 generic’ 이다.

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
33
34
35
36
37
38
39
40
41
42
class Pencil {
}

class Apple {
}

class Goods1 {
    private Object object = new Object();

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }
}

class Goods2 {
    private Object object = new Object();

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }

}

public class Test {

    public static void main(String[] args) {
        Goods1 goods1 = new Goods1();
        goods1.setObject(new Pencil());

        // ClassCastException 발생
        Apple goods1Object = (Apple) goods1.getObject();
    }
}

제네릭의 문법

제네릭 클래스와 제네릭 인터페이스 정의하기

1
2
3
4
5
6
7
8
9
10
11
12
13
class 클래스명<T> {

}

class 클래스명<K, V> {
}

interface 인터페이스명<T> {
}

interface 인터페이스명<K, V> {
}

제네릭 타입 변수의 관례적 표기 및 의미

제네릭 타입 변수 의미
T 타입(Type)
K 키(Key)
V 값(Value)
N 숫자(Number)
E 원소(Element)

제네릭 클래스의 객체 생성

생성시 new 클래스명<실제 제네릭 타입> 실제 제네릭 타입을 삽입한다는 점에서 차이가 있다.
즉, 객체를 생성할 때 제네릭 타입 변수에 실제 타입을 대입하는 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class MyClass<T> {
    private T t;

    public T get() {
        return t;
    }

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

public class Test {
    public static void main(String[] args) {
        MyClass<String> stringType = new MyClass<String>();
        stringType.set("aa");
        System.out.println(stringType.get());

        MyClass<Integer> integerType = new MyClass<Integer>();
        integerType.setT(1);
        System.out.println(integerType.getT());
    }
}

제네릭 메서드

클래스 전체를 제네릭으로 선언하는 대신, 일반 클래스 내부의 특정 메서드만 제네릭으로 선언할 수도 있다. 이를 제네릭 메서드 라고 하며, 리턴 타입 또는 입력매개변수의 타입을 제네릭 타입 변수로 선언한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class GenericMethod {

    public <T> T 메서드명(T t) {
        // 제네릭 타입 변수명이 1개일 때
    }

    public <T, V> T 메서드명(T t, V v) {
        // 제네릭 타입 변수명이 2개일 때
    }

    public <T> void 메서드명(T t) {
        // 매개변수에서만 제네릭이 사용됐을 때
    }

    public <T> T 메서드명(int t) {
        // 리턴 타입에서만 제네릭이 사용됐을 때
    }
}
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
class Example {

    public <T> T method1(T t) {
        return t;
    }

    public <T> boolean method2(T t1, T t2) {
        return t1.equals(t2);
    }

    public <K, V> void method3(K k, V v) {
        System.out.println(k + ":" + v);
    }
}

public class Test {
    public static void main(String[] args) {
        Example example = new Example();

        String 안녕 = example.<String>method1("안녕");
        boolean method2 = example.method2(2.5, 2.5);
        example.method3("국어", 80);

        System.out.println("안녕 = " + 안녕);
        System.out.println("method2 = " + method2);
    }
}

참조

Do it! 자바 완전 정복

댓글남기기