앞선 내용까지 학습하면서, 타입 파라미터 ( <T> )에 타입을 선언하여 상황에 맞게 사용하는 케이스를 살펴보았습니다. 그런데 이런 타입 파라미터를 무작정 아무 타입이나 사용 가능하게 만들어두는 경우는 많지는 않을 것입니다. 구체적으로 어떤 카테고리의 타입을 사용해야 할지 여부를 정할 필요가 있는 것이죠.
예를 들어서, 여러 타입을 넣을 수는 있지만 - 숫자 - 즉 Number 타입이나 하위 클래스 타입(Byte, Short, Integer, Long, Double)만 사용해야 하는 숫자 연산용 제네릭 메서드를 선언하는 경우가 있겠지요.
'제한된 타입 파라미터(Bounded type parameter)'를 통해 타입 파라미터를 선언하여, 상위 타입을 함께 선언하여 타입 파라미터의 선언 가능한 타입을 제한할 수 있습니다. 선언하는 방식은, 제네릭 메서드 선언 타입의 기본 형태에서 extends 키워드를 사용하면 됩니다.
참고로 상위 타입은 클래스뿐만 아니라 인터페이스 역시 적용이 가능한데, 굳이 인터페이스라고 해서 implements를 쓰거나 하지 않고 extends로만 사용합니다.
public <T extends 상위타입> 리턴타입 메서드(파라미터, ...) { // ... }
위 형태는 기존의 제네릭 메서드에서 크게 다를 것이 없기 때문에, 이해하는데 어렵지 않으실 것입니다. 여기서 타입 파라미터로 사용될 수 있는 타입은 [해당 상위 타입이거나] / [상위 타입의 하위 클래스, 또는 구현 클래스]만 해당합니다.
단, 여기서 주의할 점은 해당 제네릭 메서드 중괄호 { // ... } 안에서 타입 파라미터 변수로 사용 가능한 것은 지정된 '상위 타입의 멤버(필드, 메서드)'로 한정됩니다. 하위 타입에만 있는 필드와 메서드는 사용할 수 없습니다. 무슨 뜻인지 선뜻 와닿지 않는다면, 아래의 예시를 보겠습니다.
public class Util {
public static <T extends Number> int compare(T t1, T t2) {
double v1 = t1.doubleValue();
double v2 = t2.doubleValue();
return Double.compare(v1, v2);
}
}
위에서 T 타입이 어떤 타입이 들어오든 간에, t1 또는 t2에서는 doubleValue()라는 메서드를 사용합니다. 그럼 그럼 당연히 Number 타입에 선언된 메서드여야만 합니다. 혹시라도 Integer나 Double 타입에만 선언된 멤버를 선언해 두면 문제가 발생하겠죠?
참고로 doubleValue() 메서드는 Number 클래스에 정의된 메서드로, 특정 수를 double 타입으로 변환하는 메서드입니다. Double.compare()는 첫 번째 파라미터 값을 기준으로 합니다. 첫 번째 파라미터 값이 작으면 -1, 같으면 0, 크면 1을 리턴하게 됩니다. 이제 이 내용을 바탕으로 실행 예제를 만들어 보겠습니다.
public class Util {
public static <T extends Number> int compare(T t1, T t2) {
double v1 = t1.doubleValue();
double v2 = t2.doubleValue();
return Double.compare(v1, v2);
}
}
public class ExampleMain {
public static void main(String[] args) {
int result1 = Util.compare(10, 20);
System.out.println(result1);
int result2 = Util.compare(4.5, 2.9);
System.out.println(result2);
// String result3 = Util.compare("A", "B");
// String은 Number의 하위 타입이 아니므로 사용 불가
}
}
/* 출력
-1
1
*/
'Programming > JAVA' 카테고리의 다른 글
제네릭(6) - 제네릭 타입의 상속과 구현 (0) | 2023.05.09 |
---|---|
제네릭(5) - 와일드카드 타입 (0) | 2023.05.06 |
제네릭(3) - 제네릭 메서드 3 (0) | 2023.05.02 |
제네릭(3) - 제네릭 메서드 2 (0) | 2023.05.01 |
제네릭(3) - 제네릭 메서드 1 (0) | 2023.04.27 |