1.1 제네릭이 필요한 이유

제네릭을 사용하면 코드 재사용과 타입 안전성이라는 두 마리 토끼를 한번에 잡을 수 있다.

public class GenericBox<T> {

    private T value;

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

    public T get() {
        return value;
    }
}

사용 예제

public class BoxMain3 {

    public static void main(String[] args) {
        GenericBox<Integer> integerBox = new GenericBox<Integer>(); // 생성 시점에 T의 타입 결정
        integerBox.set(10);
        //integerBox.set("문자열");
        Integer integer = integerBox.get(); // Integer 타입 변환(캐스팅 X)

        GenericBox<String> stringBox = new GenericBox<String>(); // 생성 시점에 T의 타입 결정
//        stringBox.set(10);
        stringBox.set("문자열");
        String str = stringBox.get(); // Integer 타입 변환(캐스팅 X)
    }
}

생성 시점에 원하는 타입 지정

제네릭 클래스는 다음과 같이 정의한다.

class GenericBox<T>

<> 안에 타입 매개변수를 정의하면 된다.

제네릭 클래스는 생성하는 시점에 <> 사이에 원하는 타입을 지정한다.

new GenericBox<Integer>()

원하는 모든 타입 사용 가능

new GenericBox<Double>()
new GenericBox<Boolean>()
new GenericBox<MyClass>()

제네릭 클래스를 사용하면 위와 같이 GenericBox 객체를 생성하는 시점에 원하는 타입을 마음껏 지정할 수 있다.

참고

제네릭을 도입한다고 해서 앞서 설명한 Generic<Integer>, Generic<String> 와 같은 코드가 실제 만들어지는 것은 아니다. 대신에 자바 컴파일러가 우리가 입력한 타입 정보를 기반으로 이런 코드가 있다고 가정하고 컴파일 과정에 타입 정보를 반영한다. 이 과정에서 타입이 맞지 않으면 컴파일 오류가 발생한다.

1.2 제네릭 용어와 관례