[java] 제네릭의 타입 소거와 로타입(Raw Type)

제네릭은 자바 프로그래밍에서 타입 안전성을 보장하기 위한 강력한 도구입니다. 제네릭을 사용하면 컴파일 타임에 타입 불일치 오류를 발견할 수 있고, 코드의 가독성을 높일 수 있습니다. 하지만, 제네릭이 런타임 때 타입 정보를 소거하고 로타입이라는 것을 사용하기 때문에 몇 가지 주의할 점이 있습니다.

제네릭과 타입 소거(Type Erasure)

자바에서는 제네릭 타입 정보가 런타임 시에 소거됩니다. 컴파일러는 제네릭 타입을 Object 타입으로 변환하여 컴파일합니다. 이는 런타임 시에는 타입 정보가 소거되어 실제 객체의 타입 정보에 접근할 수 없다는 의미입니다.

예를 들어, 다음과 같은 제네릭 클래스가 있다고 가정해봅시다.

public class Box<T> {
    private T value;

    public T getValue() {
        return value;
    }

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

위의 Box 클래스를 컴파일하면 타입 소거에 의해 실제로는 다음과 같이 컴파일됩니다.

public class Box {
    private Object value;

    public Object getValue() {
        return value;
    }

    public void setValue(Object value) {
        this.value = value;
    }
}

이처럼 제네릭 타입 정보는 런타임 시에는 소거되어서 Box 클래스 내부에서는 Object 타입으로 처리됩니다.

제네릭으로 선언했지만 로타입으로 사용하는 경우

Box 클래스를 생성할 때, 다음과 같이 제네릭으로 사용해야 한다고 가정해봅시다.

Box<String> stringBox = new Box<>();

하지만, 다음과 같이 로타입으로 사용해도 컴파일러는 경고를 표시할 뿐 에러를 발생시키지 않습니다.

Box rawBox = new Box();

로타입으로 사용할 경우, 타입 안전성이 보장되지 않고, 컴파일러가 제네릭의 장점을 활용하여 코드를 검증할 수 없습니다. 따라서, 최대한 로타입을 사용하지 않고, 항상 제네릭을 올바르게 사용하는 것이 중요합니다.

결론

제네릭은 컴파일 타임에 타입 안전성을 보장하기 위한 강력한 도구이지만, 런타임 시에는 타입 정보가 소거되고 로타입이라는 것을 사용할 수 있다는 점을 주의해야 합니다. 올바른 제네릭 사용을 통해 타입 안정성을 유지하고, 코드의 가독성을 높일 수 있습니다.

자세한 내용은 Oracle 제네릭 문서를 참고하시기 바랍니다.