[java] 타입 경계(Bounded Type Parameter)를 사용한 제네릭

제네릭을 사용하면 타입 안정성(type safety) 이란 개념을 활용할 수 있습니다.

public class Box<T> {
    private T content;
    
    public T getContent() {
        return content;
    }
    
    public void setContent(T content) {
        this.content = content;
    }
}

위와 같이 Box 클래스를 제네릭으로 정의하면, Box 객체를 생성할 때 다양한 종류의 데이터 타입을 사용할 수 있습니다.

하지만 우리는 어떤 특정 클래스나 인터페이스의 하위 타입만을 허용하고 싶을 수 있습니다. 예를 들어, Number 클래스 또는 Number 인터페이스를 구현한 클래스들만을 Box에 담고 싶다고 해봅시다.

이때 사용할 수 있는 것이 타입 경계(bounded type) 입니다.

public class Box<T extends Number> {
    private T content;
    
    public T getContent() {
        return content;
    }
    
    public void setContent(T content) {
        this.content = content;
    }
}

위 코드에서 Box 클래스의 타입 매개변수 Textends Number 구문으로 상위 타입의 경계를 제한했습니다. 이제 Box 클래스가 다음과 같이 사용될 수 있습니다.

Box<Integer> intBox = new Box<>();
Box<Double> doubleBox = new Box<>();
Box<String> stringBox // 에러! String은 Number의 하위 타입이 아님

타입 경계를 사용함으로써 우리는 Box 클래스가 어떠한 Number 하위 클래스의 인스턴스만을 다룰 수 있도록 제한했습니다. 이렇게 함으로써 프로그램의 안정성을 보장할 수 있습니다.

타입 경계를 사용하는 것은 제네릭을 더욱 강력하고 유연하게 활용할 수 있는 방법 중의 하나입니다.

참고 자료