2 분 소요

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


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();
    }
}

제네릭의 문법

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

class 클래스명<T> {

}

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

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

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

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

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

제네릭 클래스의 객체 생성

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

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());
    }
}

제네릭 메서드

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

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) {
        // 리턴 타입에서만 제네릭이 사용됐을 때
    }
}
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! 자바 완전 정복

댓글남기기