Spring

<T extends Number> 랑 <? extends Number> 랑 차이

MDanderson 2023. 6. 14. 01:08

<T extends Number>와 <? extends Number> 둘 다 Number 클래스의 하위 타입을 허용하며 제네릭에서 사용되지만, 이 둘은 약간 다른 용도로 사용됩니다.

<T extends Number>: 이 형태는 클래스 또는 메소드 선언에서 제네릭 타입 T가 Number 또는 그 하위 클래스를 의미하도록 제한합니다. 이를 통해, 해당 클래스나 메소드 내에서 T는 Number의 메소드를 호출할 수 있음을 보장합니다. T는 일관적인 타입을 가지므로, 해당 클래스나 메소드 내에서 동일한 타입으로 작동합니다.

예:

 

<? extends Number>: 이 형태는 특히 메소드의 매개변수로 사용되며, Number 또는 그 하위 클래스의 인스턴스를 가진 객체를 받을 수 있음을 의미합니다. 하지만, 와일드카드(?)는 특정 타입을 지정하지 않기 때문에, 받은 객체의 타입을 알 수 없습니다. 이 형태는 보통 데이터를 읽는 상황에 주로 사용됩니다.

예:

 

제네릭 타입 T는 일반적으로 특정 타입을 지정하지 않습니다. T는 "Type Parameter"라는 의미를 가지며, 코드를 작성하는 시점에서는 이 T가 어떤 타입인지 알 수 없습니다. 즉, T는 특정 타입에 대한 플레이스홀더 역할을 합니다.

 

. 제네릭 타입 T는 코드를 작성하는 시점에서는 미정의 상태일 수 있지만, 객체를 생성하거나 메서드를 호출할 때 실제 타입이 지정됩니다. 따라서, 객체가 생성된 이후에는 T가 어떤 타입인지 알 수 있습니다.

예를 들어, List<T>라는 제네릭 타입의 리스트가 있다고 가정해 보겠습니다. 이 List<T> 타입의 리스트를 생성할 때 T에 대한 실제 타입을 지정해야 합니다:

이런 식으로 T는 객체 생성 시점에 특정 타입으로 대체됩니다. 그래서 stringList는 String 객체만 담을 수 있고, integerList는 Integer 객체만 담을 수 있습니다.

따라서, 제네릭 타입 T는 객체를 생성하는 시점에서는 특정 타입이 지정되며, 그 이후에는 해당 타입에 대한 정보를 유지하게 됩니다. 반면, 와일드카드 ?는 특정 타입을 지정하지 않고, 어떤 타입이든 허용하는 것을 의미합니다. 따라서, ?를 사용할 때는 실제 타입에 대한 정보를 얻을 수 없습니다.

 

와일드카드를 사용한 제네릭은 특정 타입으로 한정되지 않으므로, 일반적으로 해당 타입에 대한 정보를 유지하지 않습니다. 와일드카드 ?는 "알 수 없는 타입"을 의미하기 때문에, 코드 내에서 ?에 해당하는 실제 타입에 대한 정보를 얻는 것은 불가능합니다.

 

위의 경우에 list는 String 객체를 가질 수 있지만, list의 타입은 여전히 List<?>이므로 ?에 해당하는 실제 타입을 알 수 없습니다. 따라서 와일드카드를 사용하는 경우에는 데이터를 읽는 것은 가능하지만, 원래의 타입에 대한 데이터를 추가하는 것은 안전하지 않습니다.

하지만, 메소드가 호출되는 시점에서의 입력 인자의 타입에 따라 와일드카드의 타입은 결정됩니다. 즉, 메소드가 실행되는 동안에만 그 타입이 결정되고, 메소드 실행이 종료되면 그 타입 정보는 사라집니다. 이렇게 동작하는 이유는 Java가 타입 안전성을 보장하기 위한 것입니다.

그래서 와일드카드를 사용할 때는, 주로 "타입에 상관없이 작동하는 코드"를 작성할 때 사용됩니다. 예를 들어, 리스트의 모든 요소를 출력하는 메소드를 작성할 때와 같은 경우입니다. 이런 경우에는 리스트의 타입이 무엇인지 알 필요가 없으므로 와일드카드를 사용할 수 있습니다.